Commit e7420e75 authored by Darrick J. Wong's avatar Darrick J. Wong

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: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 59a2af90
......@@ -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:
......
......@@ -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;
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment