]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: pass along transaction context when reading xattr block buffers
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 31 Jul 2017 20:08:11 +0000 (15:08 -0500)
committerEric Sandeen <sandeen@redhat.com>
Mon, 31 Jul 2017 20:08:11 +0000 (15:08 -0500)
Source kernel commit: ad017f6537dee30a67b89f937a16e2f6c82e3774

Teach the extended attribute reading functions to pass along a
transaction context if one was supplied.  The extended attribute scrub
code will use transactions to lock buffers and avoid deadlocking with
itself in the case of loops; since it will already have the inode
locked, also create xattr get/list helpers that don't take locks.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_attr.c
libxfs/xfs_attr_remote.c

index 49b935039c8b3e39e465b169e43d91ad650661f8..f8250da0239a7d1dc7b9e32f567c1d538cef6edf 100644 (file)
@@ -109,6 +109,23 @@ xfs_inode_hasattr(
  * Overall external interface routines.
  *========================================================================*/
 
+/* Retrieve an extended attribute and its value.  Must have iolock. */
+int
+xfs_attr_get_ilocked(
+       struct xfs_inode        *ip,
+       struct xfs_da_args      *args)
+{
+       if (!xfs_inode_hasattr(ip))
+               return -ENOATTR;
+       else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
+               return xfs_attr_shortform_getvalue(args);
+       else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK))
+               return xfs_attr_leaf_get(args);
+       else
+               return xfs_attr_node_get(args);
+}
+
+/* Retrieve an extended attribute by name, and its value. */
 int
 xfs_attr_get(
        struct xfs_inode        *ip,
@@ -136,14 +153,7 @@ xfs_attr_get(
        args.op_flags = XFS_DA_OP_OKNOENT;
 
        lock_mode = xfs_ilock_attr_map_shared(ip);
-       if (!xfs_inode_hasattr(ip))
-               error = -ENOATTR;
-       else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
-               error = xfs_attr_shortform_getvalue(&args);
-       else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK))
-               error = xfs_attr_leaf_get(&args);
-       else
-               error = xfs_attr_node_get(&args);
+       error = xfs_attr_get_ilocked(ip, &args);
        xfs_iunlock(ip, lock_mode);
 
        *valuelenp = args.valuelen;
index 1f25e3632f262b436e00db022d2d364ca589f7cb..34c0550868a840ed9af0f5caec36ef7e71954cb0 100644 (file)
@@ -381,7 +381,8 @@ xfs_attr_rmtval_get(
                               (map[i].br_startblock != HOLESTARTBLOCK));
                        dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
                        dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
-                       error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
+                       error = xfs_trans_read_buf(mp, args->trans,
+                                                  mp->m_ddev_targp,
                                                   dblkno, dblkcnt, 0, &bp,
                                                   &xfs_attr3_rmt_buf_ops);
                        if (error)
@@ -390,7 +391,7 @@ xfs_attr_rmtval_get(
                        error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino,
                                                        &offset, &valuelen,
                                                        &dst);
-                       xfs_buf_relse(bp);
+                       xfs_trans_brelse(args->trans, bp);
                        if (error)
                                return error;