[PATCH 2/4] xfs: inode fork allocation depends on XFS_IFEXTENT flag

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

 



From: Dave Chinner <dchinner@xxxxxxxxxx>

XFS_IFEXTENT has two incompatible meanings to the code. The first
meaning is that the fork is in extent format, the second meaning is
that the extent list has been read into memory.

When the inode fork is in extent format, we automatically read the
extent list into memory and indexed by the inode extent btree when
the inode is brought into memory off disk. Hence we set the flag to
mean both "in extent format and in memory". That requires all new
fork allocations where the default state is "extent format with zero
extents" to set the XFS_IFEXTENT to indicate we've initialised the
in-memory state even though we've really done no such thing.

This fixes a scrub regression because it assumes XFS_IFEXTENT means
"on disk format" and not "read into memory" and e6a688c33238 assumed
it mean "read into memory". In reality, the XFS_IFEXTENT flag needs
to be split up into two flags - one for the on disk fork format and
one for the in-memory "extent btree has been populated" state.

Fixes: e6a688c33238 ("xfs: initialise attr fork on inode create")
Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 fs/xfs/libxfs/xfs_bmap.c       | 1 -
 fs/xfs/libxfs/xfs_inode_fork.c | 9 +++++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 5574d345d066..2f72849c05f9 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1095,7 +1095,6 @@ xfs_bmap_add_attrfork(
 	ASSERT(ip->i_afp == NULL);
 
 	ip->i_afp = xfs_ifork_alloc(XFS_DINODE_FMT_EXTENTS, 0);
-	ip->i_afp->if_flags = XFS_IFEXTENTS;
 	logflags = 0;
 	switch (ip->i_df.if_format) {
 	case XFS_DINODE_FMT_LOCAL:
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 1851d6f266d0..03e1a21848eb 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -292,6 +292,15 @@ xfs_ifork_alloc(
 	ifp = kmem_cache_zalloc(xfs_ifork_zone, GFP_NOFS | __GFP_NOFAIL);
 	ifp->if_format = format;
 	ifp->if_nextents = nextents;
+
+	/*
+	 * If this is a caller initialising a newly created fork, we need to
+	 * set XFS_IFEXTENTS to indicate the fork state is completely up to
+	 * date. Otherwise it is up to the caller to initialise the in-memory
+	 * state of the inode fork from the on-disk state.
+	 */
+	if (format == XFS_DINODE_FMT_EXTENTS && nextents == 0)
+		ifp->if_flags |= XFS_IFEXTENTS;
 	return ifp;
 }
 
-- 
2.31.0




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux