]> git.apps.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: split xfs_bmap_add_attrfork into two pieces
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:22:51 +0000 (16:22 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:03 +0000 (17:01 -0700)
Source kernel commit: 55edcd1f86474f973fccf5c5ccc8bc7908893142

Split this function into two pieces -- one to make the actual changes to
the inode core to add the attr fork, and another one to deal with
getting the transaction and locking the inodes.

The next couple of patches will need this to be split into two.  One
patch implements committing new parent pointer recordsets to damaged
files.  If one file has an attr fork and the other does not, we have to
create the missing attr fork before the atomic swap transaction, and can
use the behavior encoded in the current xfs_bmap_add_attrfork.

The second patch adapts /lost+found adoptions to handle parent pointers
correctly.  The adoption process will add a parent pointer to a child
that is being moved to /lost+found, but this requires that the attr fork
already exists.  We don't know if we're actually going to commit the
adoption until we've already reserved a transaction and taken the
ILOCKs, which means that we must have a way to bypass the start of the
current xfs_bmap_add_attrfork.

Therefore, create xfs_attr_add_fork as the helper that creates a
transaction and takes locks; and make xfs_bmap_add_attrfork the function
that updates the inode core and allocates the incore attr fork.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_attr.c
libxfs/xfs_bmap.c
libxfs/xfs_bmap.h

index 32dd7bcf5de2de35c1f1b5a4f31371c16136ca88..f94e7487969a6b3a20e279395ee0884e22f53dba 100644 (file)
@@ -947,6 +947,43 @@ xfs_attr_lookup(
        return error;
 }
 
+STATIC int
+xfs_attr_add_fork(
+       struct xfs_inode        *ip,            /* incore inode pointer */
+       int                     size,           /* space new attribute needs */
+       int                     rsvd)           /* xact may use reserved blks */
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_trans        *tp;            /* transaction pointer */
+       unsigned int            blks;           /* space reservation */
+       int                     error;          /* error return value */
+
+       ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
+
+       blks = XFS_ADDAFORK_SPACE_RES(mp);
+
+       error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0,
+                       rsvd, &tp);
+       if (error)
+               return error;
+
+       if (xfs_inode_has_attr_fork(ip))
+               goto trans_cancel;
+
+       error = xfs_bmap_add_attrfork(tp, ip, size, rsvd);
+       if (error)
+               goto trans_cancel;
+
+       error = xfs_trans_commit(tp);
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       return error;
+
+trans_cancel:
+       xfs_trans_cancel(tp);
+       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+       return error;
+}
+
 /*
  * Make a change to the xattr structure.
  *
@@ -988,7 +1025,7 @@ xfs_attr_set(
                                xfs_attr_sf_entsize_byname(args->namelen,
                                                args->valuelen);
 
-                       error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
+                       error = xfs_attr_add_fork(dp, sf_size, rsvd);
                        if (error)
                                return error;
                }
index 4cd0ffa421bfad3967fce06453f524e820b24aa8..def73fd50742c234aec197861da584eeab19f28f 100644 (file)
@@ -1019,38 +1019,29 @@ xfs_bmap_set_attrforkoff(
 }
 
 /*
- * Convert inode from non-attributed to attributed.
- * Must not be in a transaction, ip must not be locked.
+ * Convert inode from non-attributed to attributed.  Caller must hold the
+ * ILOCK_EXCL and the file cannot have an attr fork.
  */
 int                                            /* error code */
 xfs_bmap_add_attrfork(
-       xfs_inode_t             *ip,            /* incore inode pointer */
+       struct xfs_trans        *tp,
+       struct xfs_inode        *ip,            /* incore inode pointer */
        int                     size,           /* space new attribute needs */
        int                     rsvd)           /* xact may use reserved blks */
 {
-       xfs_mount_t             *mp;            /* mount structure */
-       xfs_trans_t             *tp;            /* transaction pointer */
-       int                     blks;           /* space reservation */
+       struct xfs_mount        *mp = tp->t_mountp;
        int                     version = 1;    /* superblock attr version */
        int                     logflags;       /* logging flags */
        int                     error;          /* error return value */
 
-       mp = ip->i_mount;
+       xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
        ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
-
-       blks = XFS_ADDAFORK_SPACE_RES(mp);
-
-       error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0,
-                       rsvd, &tp);
-       if (error)
-               return error;
-       if (xfs_inode_has_attr_fork(ip))
-               goto trans_cancel;
+       ASSERT(!xfs_inode_has_attr_fork(ip));
 
        xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
        error = xfs_bmap_set_attrforkoff(ip, size, &version);
        if (error)
-               goto trans_cancel;
+               return error;
 
        xfs_ifork_init_attr(ip, XFS_DINODE_FMT_EXTENTS, 0);
        logflags = 0;
@@ -1071,7 +1062,7 @@ xfs_bmap_add_attrfork(
        if (logflags)
                xfs_trans_log_inode(tp, ip, logflags);
        if (error)
-               goto trans_cancel;
+               return error;
        if (!xfs_has_attr(mp) ||
           (!xfs_has_attr2(mp) && version == 2)) {
                bool log_sb = false;
@@ -1090,14 +1081,7 @@ xfs_bmap_add_attrfork(
                        xfs_log_sb(tp);
        }
 
-       error = xfs_trans_commit(tp);
-       xfs_iunlock(ip, XFS_ILOCK_EXCL);
-       return error;
-
-trans_cancel:
-       xfs_trans_cancel(tp);
-       xfs_iunlock(ip, XFS_ILOCK_EXCL);
-       return error;
+       return 0;
 }
 
 /*
index 32fb2a455c294f627d8ce21ebc45971a37ba350a..e98849eb9bbae3d487e0b64ec293d6d4393f066b 100644 (file)
@@ -176,7 +176,8 @@ int xfs_bmap_longest_free_extent(struct xfs_perag *pag,
 void   xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
                xfs_filblks_t len);
 unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp);
-int    xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
+int    xfs_bmap_add_attrfork(struct xfs_trans *tp, struct xfs_inode *ip,
+               int size, int rsvd);
 void   xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
                struct xfs_inode *ip, int whichfork);
 int xfs_bmap_local_to_extents(struct xfs_trans *tp, struct xfs_inode *ip,