diff options
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/acl.c | 4 | ||||
-rw-r--r-- | fs/ceph/inode.c | 27 | ||||
-rw-r--r-- | fs/ceph/super.h | 1 | ||||
-rw-r--r-- | fs/ceph/xattr.c | 3 |
4 files changed, 22 insertions, 13 deletions
diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c index 4d8caeb94a11..bdb9c94335f1 100644 --- a/fs/ceph/acl.c +++ b/fs/ceph/acl.c @@ -128,7 +128,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) if (new_mode != old_mode) { newattrs.ia_mode = new_mode; newattrs.ia_valid = ATTR_MODE; - ret = ceph_setattr(dentry, &newattrs); + ret = __ceph_setattr(dentry, &newattrs); if (ret) goto out_dput; } @@ -138,7 +138,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) if (new_mode != old_mode) { newattrs.ia_mode = old_mode; newattrs.ia_valid = ATTR_MODE; - ceph_setattr(dentry, &newattrs); + __ceph_setattr(dentry, &newattrs); } goto out_dput; } diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index d98536c8abfc..9f0d99094cc1 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1773,7 +1773,7 @@ static const struct inode_operations ceph_symlink_iops = { /* * setattr */ -int ceph_setattr(struct dentry *dentry, struct iattr *attr) +int __ceph_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); struct ceph_inode_info *ci = ceph_inode(inode); @@ -1975,11 +1975,6 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if (inode_dirty_flags) __mark_inode_dirty(inode, inode_dirty_flags); - if (ia_valid & ATTR_MODE) { - err = posix_acl_chmod(inode, attr->ia_mode); - if (err) - goto out_put; - } if (mask) { req->r_inode = inode; @@ -1993,13 +1988,23 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) ceph_cap_string(dirtied), mask); ceph_mdsc_put_request(req); - if (mask & CEPH_SETATTR_SIZE) - __ceph_do_pending_vmtruncate(inode); ceph_free_cap_flush(prealloc_cf); + + if (err >= 0 && (mask & CEPH_SETATTR_SIZE)) + __ceph_do_pending_vmtruncate(inode); + return err; -out_put: - ceph_mdsc_put_request(req); - ceph_free_cap_flush(prealloc_cf); +} + +int ceph_setattr(struct dentry *dentry, struct iattr *attr) +{ + int err; + + err = __ceph_setattr(dentry, attr); + + if (err >= 0 && (attr->ia_valid & ATTR_MODE)) + err = posix_acl_chmod(d_inode(dentry), attr->ia_mode); + return err; } diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 75b7d125ce66..8c8cb8fe3d32 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -788,6 +788,7 @@ static inline int ceph_do_getattr(struct inode *inode, int mask, bool force) return __ceph_do_getattr(inode, NULL, mask, force); } extern int ceph_permission(struct inode *inode, int mask); +extern int __ceph_setattr(struct dentry *dentry, struct iattr *attr); extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 819163d8313b..b24275ef97f7 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -369,6 +369,7 @@ static int __set_xattr(struct ceph_inode_info *ci, if (update_xattr) { int err = 0; + if (xattr && (flags & XATTR_CREATE)) err = -EEXIST; else if (!xattr && (flags & XATTR_REPLACE)) @@ -376,12 +377,14 @@ static int __set_xattr(struct ceph_inode_info *ci, if (err) { kfree(name); kfree(val); + kfree(*newxattr); return err; } if (update_xattr < 0) { if (xattr) __remove_xattr(ci, xattr); kfree(name); + kfree(*newxattr); return 0; } } |