Skip to content

Commit 996a710

Browse files
Christoph HellwigAl Viro
authored andcommitted
btrfs: use generic posix ACL infrastructure
Also don't bother to set up a .get_acl method for symlinks as we do not support access control (ACLs or even mode bits) for symlinks in Linux. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 37bc153 commit 996a710

File tree

5 files changed

+28
-135
lines changed

5 files changed

+28
-135
lines changed

fs/btrfs/acl.c

Lines changed: 18 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,6 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
3535
char *value = NULL;
3636
struct posix_acl *acl;
3737

38-
if (!IS_POSIXACL(inode))
39-
return NULL;
40-
41-
acl = get_cached_acl(inode, type);
42-
if (acl != ACL_NOT_CACHED)
43-
return acl;
44-
4538
switch (type) {
4639
case ACL_TYPE_ACCESS:
4740
name = POSIX_ACL_XATTR_ACCESS;
@@ -76,31 +69,10 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
7669
return acl;
7770
}
7871

79-
static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name,
80-
void *value, size_t size, int type)
81-
{
82-
struct posix_acl *acl;
83-
int ret = 0;
84-
85-
if (!IS_POSIXACL(dentry->d_inode))
86-
return -EOPNOTSUPP;
87-
88-
acl = btrfs_get_acl(dentry->d_inode, type);
89-
90-
if (IS_ERR(acl))
91-
return PTR_ERR(acl);
92-
if (acl == NULL)
93-
return -ENODATA;
94-
ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
95-
posix_acl_release(acl);
96-
97-
return ret;
98-
}
99-
10072
/*
10173
* Needs to be called with fs_mutex held
10274
*/
103-
static int btrfs_set_acl(struct btrfs_trans_handle *trans,
75+
static int __btrfs_set_acl(struct btrfs_trans_handle *trans,
10476
struct inode *inode, struct posix_acl *acl, int type)
10577
{
10678
int ret, size = 0;
@@ -158,35 +130,9 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
158130
return ret;
159131
}
160132

161-
static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name,
162-
const void *value, size_t size, int flags, int type)
133+
int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
163134
{
164-
int ret;
165-
struct posix_acl *acl = NULL;
166-
167-
if (!inode_owner_or_capable(dentry->d_inode))
168-
return -EPERM;
169-
170-
if (!IS_POSIXACL(dentry->d_inode))
171-
return -EOPNOTSUPP;
172-
173-
if (value) {
174-
acl = posix_acl_from_xattr(&init_user_ns, value, size);
175-
if (IS_ERR(acl))
176-
return PTR_ERR(acl);
177-
178-
if (acl) {
179-
ret = posix_acl_valid(acl);
180-
if (ret)
181-
goto out;
182-
}
183-
}
184-
185-
ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type);
186-
out:
187-
posix_acl_release(acl);
188-
189-
return ret;
135+
return __btrfs_set_acl(NULL, inode, acl, type);
190136
}
191137

192138
/*
@@ -197,83 +143,31 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name,
197143
int btrfs_init_acl(struct btrfs_trans_handle *trans,
198144
struct inode *inode, struct inode *dir)
199145
{
200-
struct posix_acl *acl = NULL;
146+
struct posix_acl *default_acl, *acl;
201147
int ret = 0;
202148

203149
/* this happens with subvols */
204150
if (!dir)
205151
return 0;
206152

207-
if (!S_ISLNK(inode->i_mode)) {
208-
if (IS_POSIXACL(dir)) {
209-
acl = btrfs_get_acl(dir, ACL_TYPE_DEFAULT);
210-
if (IS_ERR(acl))
211-
return PTR_ERR(acl);
212-
}
153+
ret = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
154+
if (ret)
155+
return ret;
213156

214-
if (!acl)
215-
inode->i_mode &= ~current_umask();
157+
if (default_acl) {
158+
ret = __btrfs_set_acl(trans, inode, default_acl,
159+
ACL_TYPE_DEFAULT);
160+
posix_acl_release(default_acl);
216161
}
217162

218-
if (IS_POSIXACL(dir) && acl) {
219-
if (S_ISDIR(inode->i_mode)) {
220-
ret = btrfs_set_acl(trans, inode, acl,
221-
ACL_TYPE_DEFAULT);
222-
if (ret)
223-
goto failed;
224-
}
225-
ret = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
226-
if (ret < 0)
227-
return ret;
228-
229-
if (ret > 0) {
230-
/* we need an acl */
231-
ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS);
232-
} else if (ret < 0) {
233-
cache_no_acl(inode);
234-
}
235-
} else {
236-
cache_no_acl(inode);
163+
if (acl) {
164+
if (!ret)
165+
ret = __btrfs_set_acl(trans, inode, acl,
166+
ACL_TYPE_ACCESS);
167+
posix_acl_release(acl);
237168
}
238-
failed:
239-
posix_acl_release(acl);
240-
241-
return ret;
242-
}
243169

244-
int btrfs_acl_chmod(struct inode *inode)
245-
{
246-
struct posix_acl *acl;
247-
int ret = 0;
248-
249-
if (S_ISLNK(inode->i_mode))
250-
return -EOPNOTSUPP;
251-
252-
if (!IS_POSIXACL(inode))
253-
return 0;
254-
255-
acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
256-
if (IS_ERR_OR_NULL(acl))
257-
return PTR_ERR(acl);
258-
259-
ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
260-
if (ret)
261-
return ret;
262-
ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS);
263-
posix_acl_release(acl);
170+
if (!default_acl && !acl)
171+
cache_no_acl(inode);
264172
return ret;
265173
}
266-
267-
const struct xattr_handler btrfs_xattr_acl_default_handler = {
268-
.prefix = POSIX_ACL_XATTR_DEFAULT,
269-
.flags = ACL_TYPE_DEFAULT,
270-
.get = btrfs_xattr_acl_get,
271-
.set = btrfs_xattr_acl_set,
272-
};
273-
274-
const struct xattr_handler btrfs_xattr_acl_access_handler = {
275-
.prefix = POSIX_ACL_XATTR_ACCESS,
276-
.flags = ACL_TYPE_ACCESS,
277-
.get = btrfs_xattr_acl_get,
278-
.set = btrfs_xattr_acl_set,
279-
};

fs/btrfs/ctree.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3899,20 +3899,17 @@ do { \
38993899
/* acl.c */
39003900
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
39013901
struct posix_acl *btrfs_get_acl(struct inode *inode, int type);
3902+
int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
39023903
int btrfs_init_acl(struct btrfs_trans_handle *trans,
39033904
struct inode *inode, struct inode *dir);
3904-
int btrfs_acl_chmod(struct inode *inode);
39053905
#else
39063906
#define btrfs_get_acl NULL
3907+
#define btrfs_set_acl NULL
39073908
static inline int btrfs_init_acl(struct btrfs_trans_handle *trans,
39083909
struct inode *inode, struct inode *dir)
39093910
{
39103911
return 0;
39113912
}
3912-
static inline int btrfs_acl_chmod(struct inode *inode)
3913-
{
3914-
return 0;
3915-
}
39163913
#endif
39173914

39183915
/* relocation.c */

fs/btrfs/inode.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4464,7 +4464,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
44644464
err = btrfs_dirty_inode(inode);
44654465

44664466
if (!err && attr->ia_valid & ATTR_MODE)
4467-
err = btrfs_acl_chmod(inode);
4467+
err = posix_acl_chmod(inode, inode->i_mode);
44684468
}
44694469

44704470
return err;
@@ -8649,12 +8649,14 @@ static const struct inode_operations btrfs_dir_inode_operations = {
86498649
.removexattr = btrfs_removexattr,
86508650
.permission = btrfs_permission,
86518651
.get_acl = btrfs_get_acl,
8652+
.set_acl = btrfs_set_acl,
86528653
.update_time = btrfs_update_time,
86538654
};
86548655
static const struct inode_operations btrfs_dir_ro_inode_operations = {
86558656
.lookup = btrfs_lookup,
86568657
.permission = btrfs_permission,
86578658
.get_acl = btrfs_get_acl,
8659+
.set_acl = btrfs_set_acl,
86588660
.update_time = btrfs_update_time,
86598661
};
86608662

@@ -8724,6 +8726,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
87248726
.permission = btrfs_permission,
87258727
.fiemap = btrfs_fiemap,
87268728
.get_acl = btrfs_get_acl,
8729+
.set_acl = btrfs_set_acl,
87278730
.update_time = btrfs_update_time,
87288731
};
87298732
static const struct inode_operations btrfs_special_inode_operations = {
@@ -8735,6 +8738,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
87358738
.listxattr = btrfs_listxattr,
87368739
.removexattr = btrfs_removexattr,
87378740
.get_acl = btrfs_get_acl,
8741+
.set_acl = btrfs_set_acl,
87388742
.update_time = btrfs_update_time,
87398743
};
87408744
static const struct inode_operations btrfs_symlink_inode_operations = {
@@ -8748,7 +8752,6 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
87488752
.getxattr = btrfs_getxattr,
87498753
.listxattr = btrfs_listxattr,
87508754
.removexattr = btrfs_removexattr,
8751-
.get_acl = btrfs_get_acl,
87528755
.update_time = btrfs_update_time,
87538756
};
87548757

fs/btrfs/xattr.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/rwsem.h>
2323
#include <linux/xattr.h>
2424
#include <linux/security.h>
25+
#include <linux/posix_acl_xattr.h>
2526
#include "ctree.h"
2627
#include "btrfs_inode.h"
2728
#include "transaction.h"
@@ -313,8 +314,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
313314
*/
314315
const struct xattr_handler *btrfs_xattr_handlers[] = {
315316
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
316-
&btrfs_xattr_acl_access_handler,
317-
&btrfs_xattr_acl_default_handler,
317+
&posix_acl_access_xattr_handler,
318+
&posix_acl_default_xattr_handler,
318319
#endif
319320
NULL,
320321
};

fs/btrfs/xattr.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121

2222
#include <linux/xattr.h>
2323

24-
extern const struct xattr_handler btrfs_xattr_acl_access_handler;
25-
extern const struct xattr_handler btrfs_xattr_acl_default_handler;
2624
extern const struct xattr_handler *btrfs_xattr_handlers[];
2725

2826
extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name,

0 commit comments

Comments
 (0)