Commit 5d24ec4c authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarGao Xiang <hsiangkao@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 26f88363
Loading
Loading
Loading
Loading
+22 −18
Original line number Diff line number Diff line
@@ -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;

	if (mode != inode->i_mode) {
		struct iattr iattr;
	struct xfs_inode	*ip = XFS_I(inode);
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_trans	*tp;
	int			error;

		iattr.ia_valid = ATTR_MODE | ATTR_CTIME;
		iattr.ia_mode = mode;
		iattr.ia_ctime = current_time(inode);
	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
	if (error)
		return error;

		error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL);
	}
	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);

	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;
}

+5 −6
Original line number Diff line number Diff line
@@ -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;
+0 −7
Original line number Diff line number Diff line
@@ -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__ */