summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_acl.c40
-rw-r--r--fs/xfs/xfs_iops.c11
-rw-r--r--fs/xfs/xfs_iops.h7
3 files changed, 27 insertions, 31 deletions
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index c544951a0c07..779cb73b3d00 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -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;
}
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index a0644da67321..67c8dc9de8aa 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -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;
diff --git a/fs/xfs/xfs_iops.h b/fs/xfs/xfs_iops.h
index a91e2d1b47b4..99ca745c1071 100644
--- a/fs/xfs/xfs_iops.h
+++ b/fs/xfs/xfs_iops.h
@@ -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__ */