xfs: open code updating i_mode in xfs_set_acl

Rather than going through the big and hairy xfs_setattr_nonsize function,
just open code a transactional i_mode and i_ctime update.  This allows
to mark xfs_setattr_nonsize and remove the flags argument to it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
Christoph Hellwig 2020-12-10 20:00:39 -08:00 committed by Darrick J. Wong
parent 26f88363ec
commit 5d24ec4c7d
3 changed files with 27 additions and 31 deletions

View File

@ -16,6 +16,7 @@
#include "xfs_acl.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_trans.h"
#include <linux/posix_acl_xattr.h>
@ -212,21 +213,28 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
}
static int
xfs_set_mode(struct inode *inode, umode_t mode)
xfs_acl_set_mode(
struct inode *inode,
umode_t mode)
{
int error = 0;
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
struct xfs_trans *tp;
int error;
if (mode != inode->i_mode) {
struct iattr iattr;
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
if (error)
return error;
iattr.ia_valid = ATTR_MODE | ATTR_CTIME;
iattr.ia_mode = mode;
iattr.ia_ctime = current_time(inode);
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
inode->i_mode = mode;
inode->i_ctime = current_time(inode);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL);
}
return error;
if (mp->m_flags & XFS_MOUNT_WSYNC)
xfs_trans_set_sync(tp);
return xfs_trans_commit(tp);
}
int
@ -251,18 +259,14 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
}
set_acl:
error = __xfs_set_acl(inode, acl, type);
if (error)
return error;
/*
* We set the mode after successfully updating the ACL xattr because the
* xattr update can fail at ENOSPC and we don't want to change the mode
* if the ACL update hasn't been applied.
*/
if (set_mode)
error = xfs_set_mode(inode, mode);
error = __xfs_set_acl(inode, acl, type);
if (!error && set_mode && mode != inode->i_mode)
error = xfs_acl_set_mode(inode, mode);
return error;
}

View File

@ -646,11 +646,10 @@ xfs_vn_change_ok(
* Caution: The caller of this function is responsible for calling
* setattr_prepare() or otherwise verifying the change is fine.
*/
int
static int
xfs_setattr_nonsize(
struct xfs_inode *ip,
struct iattr *iattr,
int flags)
struct iattr *iattr)
{
xfs_mount_t *mp = ip->i_mount;
struct inode *inode = VFS_I(ip);
@ -807,7 +806,7 @@ xfs_setattr_nonsize(
* to attr_set. No previous user of the generic
* Posix ACL code seems to care about this issue either.
*/
if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
if (mask & ATTR_MODE) {
error = posix_acl_chmod(inode, inode->i_mode);
if (error)
return error;
@ -863,7 +862,7 @@ xfs_setattr_size(
* Use the regular setattr path to update the timestamps.
*/
iattr->ia_valid &= ~ATTR_SIZE;
return xfs_setattr_nonsize(ip, iattr, 0);
return xfs_setattr_nonsize(ip, iattr);
}
/*
@ -1074,7 +1073,7 @@ xfs_vn_setattr(
error = xfs_vn_change_ok(dentry, iattr);
if (!error)
error = xfs_setattr_nonsize(ip, iattr, 0);
error = xfs_setattr_nonsize(ip, iattr);
}
return error;

View File

@ -13,14 +13,7 @@ extern const struct file_operations xfs_dir_file_operations;
extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
/*
* Internal setattr interfaces.
*/
#define XFS_ATTR_NOACL 0x01 /* Don't call posix_acl_chmod */
extern void xfs_setattr_time(struct xfs_inode *ip, struct iattr *iattr);
extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap,
int flags);
extern int xfs_vn_setattr_size(struct dentry *dentry, struct iattr *vap);
#endif /* __XFS_IOPS_H__ */