summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-05-24 19:49:41 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-06-01 17:28:35 -0400
commit55ecefff61941145f99378076799e0e4604b2e83 (patch)
tree06c63f5c5c0f27527cd469a78079a714f9c71aa0
parentc6c26694cdf686320a2f2688a93d98d21b4b35b4 (diff)
bcachefs: fix SGID + acls
-rw-r--r--fs/bcachefs/acl.c59
-rw-r--r--fs/bcachefs/acl.h6
-rw-r--r--fs/bcachefs/fs.c4
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;
}