--- /dev/null
+From stable-bounces@linux.kernel.org Tue Jun 6 20:00:50 2006
+Date: Tue, 6 Jun 2006 22:54:44 -0400
+From: Chuck Ebbert <76306.1226@compuserve.com>
+To: linux-stable <stable@kernel.org>
+Cc: Dave Kleikamp <shaggy@austin.ibm.com>
+Subject: JFS: Fix multiple errors in metapage_releasepage
+
+From: Dave Kleikamp <shaggy@austin.ibm.com>
+
+It looks like metapage_releasepage was making in invalid assumption that
+the releasepage method would not be called on a dirty page. Instead of
+issuing a warning and releasing the metapage, it should return 0, indicating
+that the private data for the page cannot be released.
+
+I also realized that metapage_releasepage had the return code all wrong. If
+it is successful in releasing the private data, it should return 1, otherwise
+it needs to return 0.
+
+Lastly, there is no need to call wait_on_page_writeback, since
+try_to_release_page will not call us with a page in writback state.
+
+Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ fs/jfs/jfs_metapage.c | 20 +++++---------------
+ 1 file changed, 5 insertions(+), 15 deletions(-)
+
+--- linux-2.6.16.20.orig/fs/jfs/jfs_metapage.c
++++ linux-2.6.16.20/fs/jfs/jfs_metapage.c
+@@ -543,7 +543,7 @@ add_failed:
+ static int metapage_releasepage(struct page *page, gfp_t gfp_mask)
+ {
+ struct metapage *mp;
+- int busy = 0;
++ int ret = 1;
+ unsigned int offset;
+
+ for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) {
+@@ -553,30 +553,20 @@ static int metapage_releasepage(struct p
+ continue;
+
+ jfs_info("metapage_releasepage: mp = 0x%p", mp);
+- if (mp->count || mp->nohomeok) {
++ if (mp->count || mp->nohomeok ||
++ test_bit(META_dirty, &mp->flag)) {
+ jfs_info("count = %ld, nohomeok = %d", mp->count,
+ mp->nohomeok);
+- busy = 1;
++ ret = 0;
+ continue;
+ }
+- wait_on_page_writeback(page);
+- //WARN_ON(test_bit(META_dirty, &mp->flag));
+- if (test_bit(META_dirty, &mp->flag)) {
+- dump_mem("dirty mp in metapage_releasepage", mp,
+- sizeof(struct metapage));
+- dump_mem("page", page, sizeof(struct page));
+- dump_stack();
+- }
+ if (mp->lsn)
+ remove_from_logsync(mp);
+ remove_metapage(page, mp);
+ INCREMENT(mpStat.pagefree);
+ free_metapage(mp);
+ }
+- if (busy)
+- return -1;
+-
+- return 0;
++ return ret;
+ }
+
+ static int metapage_invalidatepage(struct page *page, unsigned long offset)