summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode_item.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2021-03-29 11:11:38 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-04-07 14:37:03 -0700
commit9b3beb028ff5bed99473021d1a7de8747665ac32 (patch)
treed33f9c76a931fff692c597900a70f06e49850d9e /fs/xfs/xfs_inode_item.c
parent55f773380e922d3b975a7acb24331c76611cce30 (diff)
downloadlinux-9b3beb028ff5bed99473021d1a7de8747665ac32.tar.bz2
xfs: remove the di_dmevmask and di_dmstate fields from struct xfs_icdinode
The legacy DMAPI fields were never set by upstream Linux XFS, and have no way to be read using the kernel APIs. So instead of bloating the in-core inode for them just copy them from the on-disk inode into the log when logging the inode. The only caveat is that we need to make sure to zero the fields for newly read or deleted inodes, which is solved using a new flag in the inode. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/xfs_inode_item.c')
-rw-r--r--fs/xfs/xfs_inode_item.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 17e20a6d8b4e..16e758a68921 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -317,6 +317,33 @@ xfs_inode_to_log_dinode_ts(
return its;
}
+/*
+ * The legacy DMAPI fields are only present in the on-disk and in-log inodes,
+ * but not in the in-memory one. But we are guaranteed to have an inode buffer
+ * in memory when logging an inode, so we can just copy it from the on-disk
+ * inode to the in-log inode here so that recovery of file system with these
+ * fields set to non-zero values doesn't lose them. For all other cases we zero
+ * the fields.
+ */
+static void
+xfs_copy_dm_fields_to_log_dinode(
+ struct xfs_inode *ip,
+ struct xfs_log_dinode *to)
+{
+ struct xfs_dinode *dip;
+
+ dip = xfs_buf_offset(ip->i_itemp->ili_item.li_buf,
+ ip->i_imap.im_boffset);
+
+ if (xfs_iflags_test(ip, XFS_IPRESERVE_DM_FIELDS)) {
+ to->di_dmevmask = be32_to_cpu(dip->di_dmevmask);
+ to->di_dmstate = be16_to_cpu(dip->di_dmstate);
+ } else {
+ to->di_dmevmask = 0;
+ to->di_dmstate = 0;
+ }
+}
+
static void
xfs_inode_to_log_dinode(
struct xfs_inode *ip,
@@ -349,10 +376,10 @@ xfs_inode_to_log_dinode(
to->di_anextents = xfs_ifork_nextents(ip->i_afp);
to->di_forkoff = from->di_forkoff;
to->di_aformat = xfs_ifork_format(ip->i_afp);
- to->di_dmevmask = from->di_dmevmask;
- to->di_dmstate = from->di_dmstate;
to->di_flags = from->di_flags;
+ xfs_copy_dm_fields_to_log_dinode(ip, to);
+
/* log a dummy value to ensure log structure is fully initialised */
to->di_next_unlinked = NULLAGINO;