[PATCH] jfs: Release even dirty metapages on invalidate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This isn't going to apply to your tree; it will apply to today's -next
though.  Happy to take this on top of my current pagecache patch set
with appropriate acks.  Maybe it's the wrong fix; I haven't spent very
long trying to understand what all the parts of mp mean ... maybe it
should only override the META_Dirty check and it needs to do something
else for the other two checks?

--- 8< ---

For ->release_folio(), we can fail to release the metapage if, for
example, it's dirty.  For ->invalidate_folio(), we must release the
metapage as the page is being removed and will be freed.  Failing to
release the metapage results in xfstests generic/537 hitting BUG reports
like this:

BUG: Bad page state in process umount  pfn:12b03a
page:000000000c3e2db5 refcount:0 mapcount:0 mapping:0000000000000000 index:0x10 pfn:0x12b03a
flags: 0x8000000000002004(uptodate|private|zone=2)
raw: 8000000000002004 ffffea000417a5c8 ffff88810a41bbe0 0000000000000000
raw: 0000000000000010 ffff888124e12680 00000000ffffffff 0000000000000000
page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set

as the page allocator checks that the page no longer has private data.

Add a bool argument to inform the release routine whether to override
the checks and release the metapage anyway.

Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx>
---
 fs/jfs/jfs_metapage.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 2e8461ce74de..5b4f0cd8d276 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -524,7 +524,8 @@ static int metapage_read_folio(struct file *fp, struct folio *folio)
 	return -EIO;
 }
 
-static bool metapage_release_folio(struct folio *folio, gfp_t gfp_mask)
+static bool __metapage_release_folio(struct folio *folio, gfp_t gfp_mask,
+		bool force)
 {
 	struct metapage *mp;
 	bool ret = true;
@@ -537,8 +538,9 @@ static bool metapage_release_folio(struct folio *folio, gfp_t gfp_mask)
 			continue;
 
 		jfs_info("metapage_release_folio: mp = 0x%p", mp);
-		if (mp->count || mp->nohomeok ||
-		    test_bit(META_dirty, &mp->flag)) {
+		if (!force &&
+		    (mp->count || mp->nohomeok ||
+		     test_bit(META_dirty, &mp->flag))) {
 			jfs_info("count = %ld, nohomeok = %d", mp->count,
 				 mp->nohomeok);
 			ret = false;
@@ -553,6 +555,11 @@ static bool metapage_release_folio(struct folio *folio, gfp_t gfp_mask)
 	return ret;
 }
 
+static bool metapage_release_folio(struct folio *folio, gfp_t gfp)
+{
+	return __metapage_release_folio(folio, gfp, false);
+}
+
 static void metapage_invalidate_folio(struct folio *folio, size_t offset,
 				    size_t length)
 {
@@ -560,7 +567,7 @@ static void metapage_invalidate_folio(struct folio *folio, size_t offset,
 
 	BUG_ON(folio_test_writeback(folio));
 
-	metapage_release_folio(folio, 0);
+	__metapage_release_folio(folio, 0, true);
 }
 
 const struct address_space_operations jfs_metapage_aops = {
-- 
2.34.1




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux