summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2024-04-22 09:48:06 -0700
committerDarrick J. Wong <djwong@kernel.org>2024-04-23 07:47:03 -0700
commite7420e75ef04787bc51688fc9bbca7da4d164a1e (patch)
tree528ada4f72e85e5327f2792e71df149e5a4ae0a5 /fs
parent59a2af9086f0d60fc8de7346da67db7d764c7221 (diff)
downloadlinux-stable-e7420e75ef04787bc51688fc9bbca7da4d164a1e.tar.gz
linux-stable-e7420e75ef04787bc51688fc9bbca7da4d164a1e.tar.bz2
linux-stable-e7420e75ef04787bc51688fc9bbca7da4d164a1e.zip
xfs: remove some boilerplate from xfs_attr_set
In preparation for online/offline repair wanting to use xfs_attr_set, move some of the boilerplate out of this function into the callers. Repair can initialize the da_args completely, and the userspace flag handling/twisting goes away once we move it to xfs_attr_change. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/libxfs/xfs_attr.c33
-rw-r--r--fs/xfs/scrub/attr_repair.c4
-rw-r--r--fs/xfs/xfs_xattr.c24
3 files changed, 38 insertions, 23 deletions
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 8c283e5c2470..df8418671c37 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -948,6 +948,16 @@ xfs_attr_lookup(
return error;
}
+/*
+ * Make a change to the xattr structure.
+ *
+ * The caller must have initialized @args, attached dquots, and must not hold
+ * any ILOCKs.
+ *
+ * Returns -EEXIST for XFS_ATTRUPDATE_CREATE if the name already exists.
+ * Returns -ENOATTR for XFS_ATTRUPDATE_REMOVE if the name does not exist.
+ * Returns 0 on success, or a negative errno if something else went wrong.
+ */
int
xfs_attr_set(
struct xfs_da_args *args,
@@ -961,27 +971,7 @@ xfs_attr_set(
int rmt_blks = 0;
unsigned int total;
- if (xfs_is_shutdown(dp->i_mount))
- return -EIO;
-
- error = xfs_qm_dqattach(dp);
- if (error)
- return error;
-
- if (!args->owner)
- args->owner = args->dp->i_ino;
- args->geo = mp->m_attr_geo;
- args->whichfork = XFS_ATTR_FORK;
- xfs_attr_sethash(args);
-
- /*
- * We have no control over the attribute names that userspace passes us
- * to remove, so we have to allow the name lookup prior to attribute
- * removal to fail as well. Preserve the logged flag, since we need
- * to pass that through to the logging code.
- */
- args->op_flags = XFS_DA_OP_OKNOENT |
- (args->op_flags & XFS_DA_OP_LOGGED);
+ ASSERT(!args->trans);
switch (op) {
case XFS_ATTRUPDATE_UPSERT:
@@ -1076,6 +1066,7 @@ xfs_attr_set(
error = xfs_trans_commit(args->trans);
out_unlock:
xfs_iunlock(dp, XFS_ILOCK_EXCL);
+ args->trans = NULL;
return error;
out_trans_cancel:
diff --git a/fs/xfs/scrub/attr_repair.c b/fs/xfs/scrub/attr_repair.c
index 8b89c112c492..67c0ec0d1dbb 100644
--- a/fs/xfs/scrub/attr_repair.c
+++ b/fs/xfs/scrub/attr_repair.c
@@ -558,6 +558,9 @@ xrep_xattr_insert_rec(
.namelen = key->namelen,
.valuelen = key->valuelen,
.owner = rx->sc->ip->i_ino,
+ .geo = rx->sc->mp->m_attr_geo,
+ .whichfork = XFS_ATTR_FORK,
+ .op_flags = XFS_DA_OP_OKNOENT,
};
struct xchk_xattr_buf *ab = rx->sc->buf;
int error;
@@ -602,6 +605,7 @@ xrep_xattr_insert_rec(
* xfs_attr_set creates and commits its own transaction. If the attr
* already exists, we'll just drop it during the rebuild.
*/
+ xfs_attr_sethash(&args);
error = xfs_attr_set(&args, XFS_ATTRUPDATE_CREATE);
if (error == -EEXIST)
error = 0;
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index b43f7081b0f4..bbdbe9026658 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -17,6 +17,7 @@
#include "xfs_acl.h"
#include "xfs_log.h"
#include "xfs_xattr.h"
+#include "xfs_quota.h"
#include <linux/posix_acl_xattr.h>
@@ -70,7 +71,9 @@ xfs_attr_want_log_assist(
/*
* Set or remove an xattr, having grabbed the appropriate logging resources
- * prior to calling libxfs.
+ * prior to calling libxfs. Callers of this function are only required to
+ * initialize the inode, attr_filter, name, namelen, value, and valuelen fields
+ * of @args.
*/
int
xfs_attr_change(
@@ -80,7 +83,19 @@ xfs_attr_change(
struct xfs_mount *mp = args->dp->i_mount;
int error;
- ASSERT(!(args->op_flags & XFS_DA_OP_LOGGED));
+ if (xfs_is_shutdown(mp))
+ return -EIO;
+
+ error = xfs_qm_dqattach(args->dp);
+ if (error)
+ return error;
+
+ /*
+ * We have no control over the attribute names that userspace passes us
+ * to remove, so we have to allow the name lookup prior to attribute
+ * removal to fail as well.
+ */
+ args->op_flags = XFS_DA_OP_OKNOENT;
if (xfs_attr_want_log_assist(mp)) {
error = xfs_attr_grab_log_assist(mp);
@@ -90,6 +105,11 @@ xfs_attr_change(
args->op_flags |= XFS_DA_OP_LOGGED;
}
+ args->owner = args->dp->i_ino;
+ args->geo = mp->m_attr_geo;
+ args->whichfork = XFS_ATTR_FORK;
+ xfs_attr_sethash(args);
+
return xfs_attr_set(args, op);
}