diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-05-24 19:49:41 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-06-01 17:28:35 -0400 |
commit | 55ecefff61941145f99378076799e0e4604b2e83 (patch) | |
tree | 06c63f5c5c0f27527cd469a78079a714f9c71aa0 | |
parent | c6c26694cdf686320a2f2688a93d98d21b4b35b4 (diff) |
bcachefs: fix SGID + acls
-rw-r--r-- | fs/bcachefs/acl.c | 59 | ||||
-rw-r--r-- | fs/bcachefs/acl.h | 6 | ||||
-rw-r--r-- | fs/bcachefs/fs.c | 4 |
3 files changed, 38 insertions, 31 deletions
diff --git a/fs/bcachefs/acl.c b/fs/bcachefs/acl.c index d29bdafaea66..29774e5d94f9 100644 --- a/fs/bcachefs/acl.c +++ b/fs/bcachefs/acl.c @@ -176,34 +176,19 @@ struct posix_acl *bch2_get_acl(struct inode *vinode, int type) return acl; } -int bch2_set_acl(struct inode *vinode, struct posix_acl *acl, int type) +int __bch2_set_acl(struct inode *vinode, struct posix_acl *acl, int type) { struct bch_inode_info *inode = to_bch_ei(vinode); struct bch_fs *c = inode->v.i_sb->s_fs_info; - umode_t mode = inode->v.i_mode; int name_index; void *value = NULL; size_t size = 0; int ret; - if (type == ACL_TYPE_ACCESS && acl) { - ret = posix_acl_update_mode(&inode->v, &mode, &acl); - if (ret) - return ret; - } - switch (type) { case ACL_TYPE_ACCESS: name_index = BCH_XATTR_INDEX_POSIX_ACL_ACCESS; - if (acl) { - ret = posix_acl_equiv_mode(acl, &inode->v.i_mode); - if (ret < 0) - return ret; - if (ret == 0) - acl = NULL; - } break; - case ACL_TYPE_DEFAULT: name_index = BCH_XATTR_INDEX_POSIX_ACL_DEFAULT; if (!S_ISDIR(inode->v.i_mode)) @@ -220,20 +205,7 @@ int bch2_set_acl(struct inode *vinode, struct posix_acl *acl, int type) return (int)PTR_ERR(value); } - if (mode != inode->v.i_mode) { - mutex_lock(&inode->ei_update_lock); - inode->v.i_mode = mode; - inode->v.i_ctime = current_time(&inode->v); - - ret = bch2_write_inode(c, inode); - mutex_unlock(&inode->ei_update_lock); - - if (ret) - goto err; - } - ret = bch2_xattr_set(c, inode, "", value, size, 0, name_index); -err: kfree(value); if (ret == -ERANGE) @@ -245,4 +217,33 @@ err: return ret; } +int bch2_set_acl(struct inode *vinode, struct posix_acl *acl, int type) +{ + struct bch_inode_info *inode = to_bch_ei(vinode); + struct bch_fs *c = inode->v.i_sb->s_fs_info; + umode_t mode = inode->v.i_mode; + int ret; + + if (type == ACL_TYPE_ACCESS && acl) { + ret = posix_acl_update_mode(&inode->v, &mode, &acl); + if (ret) + return ret; + } + + ret = __bch2_set_acl(vinode, acl, type); + if (ret) + return ret; + + if (mode != inode->v.i_mode) { + mutex_lock(&inode->ei_update_lock); + inode->v.i_mode = mode; + inode->v.i_ctime = current_time(&inode->v); + + ret = bch2_write_inode(c, inode); + mutex_unlock(&inode->ei_update_lock); + } + + return ret; +} + #endif /* CONFIG_BCACHEFS_POSIX_ACL */ diff --git a/fs/bcachefs/acl.h b/fs/bcachefs/acl.h index b721330e2837..a66338d4171e 100644 --- a/fs/bcachefs/acl.h +++ b/fs/bcachefs/acl.h @@ -52,10 +52,16 @@ static inline int bch2_acl_count(size_t size) struct posix_acl; extern struct posix_acl *bch2_get_acl(struct inode *, int); +extern int __bch2_set_acl(struct inode *, struct posix_acl *, int); extern int bch2_set_acl(struct inode *, struct posix_acl *, int); #else +static inline int __bch2_set_acl(struct inode *inode, struct posix_acl *acl, int type) +{ + return 0; +} + static inline int bch2_set_acl(struct inode *inode, struct posix_acl *acl, int type) { return 0; diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index fb30f0d95377..dc6c651df2f3 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -243,13 +243,13 @@ static struct bch_inode_info *bch2_vfs_inode_create(struct bch_fs *c, atomic_long_inc(&c->nr_inodes); if (default_acl) { - ret = bch2_set_acl(&inode->v, default_acl, ACL_TYPE_DEFAULT); + ret = __bch2_set_acl(&inode->v, default_acl, ACL_TYPE_DEFAULT); if (unlikely(ret)) goto err; } if (acl) { - ret = bch2_set_acl(&inode->v, acl, ACL_TYPE_ACCESS); + ret = __bch2_set_acl(&inode->v, acl, ACL_TYPE_ACCESS); if (unlikely(ret)) goto err; } |