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>
This commit is contained in:
Christoph Hellwig 2021-03-29 11:11:38 -07:00 committed by Darrick J. Wong
parent 55f773380e
commit 9b3beb028f
6 changed files with 35 additions and 17 deletions

View File

@ -230,10 +230,11 @@ xfs_inode_from_disk(
to->di_nblocks = be64_to_cpu(from->di_nblocks);
to->di_extsize = be32_to_cpu(from->di_extsize);
to->di_forkoff = from->di_forkoff;
to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
to->di_dmstate = be16_to_cpu(from->di_dmstate);
to->di_flags = be16_to_cpu(from->di_flags);
if (from->di_dmevmask || from->di_dmstate)
xfs_iflags_set(ip, XFS_IPRESERVE_DM_FIELDS);
if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {
inode_set_iversion_queried(inode,
be64_to_cpu(from->di_changecount));
@ -311,8 +312,6 @@ xfs_inode_to_disk(
to->di_anextents = cpu_to_be16(xfs_ifork_nextents(ip->i_afp));
to->di_forkoff = from->di_forkoff;
to->di_aformat = xfs_ifork_format(ip->i_afp);
to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
to->di_dmstate = cpu_to_be16(from->di_dmstate);
to->di_flags = cpu_to_be16(from->di_flags);
if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {

View File

@ -22,8 +22,6 @@ struct xfs_icdinode {
xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
uint32_t di_dmevmask; /* DMIG event mask */
uint16_t di_dmstate; /* DMIG state info */
uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
uint64_t di_flags2; /* more random flags */

View File

@ -840,8 +840,6 @@ xfs_init_new_inode(
inode->i_ctime = tv;
ip->i_d.di_extsize = 0;
ip->i_d.di_dmevmask = 0;
ip->i_d.di_dmstate = 0;
ip->i_d.di_flags = 0;
if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
@ -2615,9 +2613,10 @@ xfs_ifree(
VFS_I(ip)->i_mode = 0; /* mark incore inode as free */
ip->i_d.di_flags = 0;
ip->i_d.di_flags2 = ip->i_mount->m_ino_geo.new_diflags2;
ip->i_d.di_dmevmask = 0;
ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
if (xfs_iflags_test(ip, XFS_IPRESERVE_DM_FIELDS))
xfs_iflags_clear(ip, XFS_IPRESERVE_DM_FIELDS);
/* Don't attempt to replay owner changes for a deleted inode */
spin_lock(&iip->ili_lock);

View File

@ -222,6 +222,7 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
#define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */
#define __XFS_INEW_BIT 3 /* inode has just been allocated */
#define XFS_INEW (1 << __XFS_INEW_BIT)
#define XFS_IPRESERVE_DM_FIELDS (1 << 4) /* has legacy DMAPI fields set */
#define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */
#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */
#define XFS_IFLUSHING (1 << 7) /* inode is being flushed */

View File

@ -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;

View File

@ -2696,12 +2696,6 @@ xlog_recover_process_one_iunlink(
agino = be32_to_cpu(dip->di_next_unlinked);
xfs_buf_relse(ibp);
/*
* Prevent any DMAPI event from being sent when the reference on
* the inode is dropped.
*/
ip->i_d.di_dmevmask = 0;
xfs_irele(ip);
return agino;