Skip to content

Commit 013cdf1

Browse files
Christoph HellwigAl Viro
authored andcommitted
nfs: use generic posix ACL infrastructure for v3 Posix ACLs
This causes a small behaviour change in that we don't bother to set ACLs on file creation if the mode bit can express the access permissions fully, and thus behaving identical to local filesystems. Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent e01580b commit 013cdf1

File tree

6 files changed

+121
-281
lines changed

6 files changed

+121
-281
lines changed

fs/nfs/inode.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,10 +1641,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
16411641
return NULL;
16421642
nfsi->flags = 0UL;
16431643
nfsi->cache_validity = 0UL;
1644-
#ifdef CONFIG_NFS_V3_ACL
1645-
nfsi->acl_access = ERR_PTR(-EAGAIN);
1646-
nfsi->acl_default = ERR_PTR(-EAGAIN);
1647-
#endif
16481644
#if IS_ENABLED(CONFIG_NFS_V4)
16491645
nfsi->nfs4_acl = NULL;
16501646
#endif /* CONFIG_NFS_V4 */

fs/nfs/nfs3acl.c

Lines changed: 55 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -10,179 +10,7 @@
1010

1111
#define NFSDBG_FACILITY NFSDBG_PROC
1212

13-
ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
14-
{
15-
struct inode *inode = dentry->d_inode;
16-
struct posix_acl *acl;
17-
int pos=0, len=0;
18-
19-
# define output(s) do { \
20-
if (pos + sizeof(s) <= size) { \
21-
memcpy(buffer + pos, s, sizeof(s)); \
22-
pos += sizeof(s); \
23-
} \
24-
len += sizeof(s); \
25-
} while(0)
26-
27-
acl = nfs3_proc_getacl(inode, ACL_TYPE_ACCESS);
28-
if (IS_ERR(acl))
29-
return PTR_ERR(acl);
30-
if (acl) {
31-
output("system.posix_acl_access");
32-
posix_acl_release(acl);
33-
}
34-
35-
if (S_ISDIR(inode->i_mode)) {
36-
acl = nfs3_proc_getacl(inode, ACL_TYPE_DEFAULT);
37-
if (IS_ERR(acl))
38-
return PTR_ERR(acl);
39-
if (acl) {
40-
output("system.posix_acl_default");
41-
posix_acl_release(acl);
42-
}
43-
}
44-
45-
# undef output
46-
47-
if (!buffer || len <= size)
48-
return len;
49-
return -ERANGE;
50-
}
51-
52-
ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
53-
void *buffer, size_t size)
54-
{
55-
struct inode *inode = dentry->d_inode;
56-
struct posix_acl *acl;
57-
int type, error = 0;
58-
59-
if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
60-
type = ACL_TYPE_ACCESS;
61-
else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
62-
type = ACL_TYPE_DEFAULT;
63-
else
64-
return -EOPNOTSUPP;
65-
66-
acl = nfs3_proc_getacl(inode, type);
67-
if (IS_ERR(acl))
68-
return PTR_ERR(acl);
69-
else if (acl) {
70-
if (type == ACL_TYPE_ACCESS && acl->a_count == 0)
71-
error = -ENODATA;
72-
else
73-
error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
74-
posix_acl_release(acl);
75-
} else
76-
error = -ENODATA;
77-
78-
return error;
79-
}
80-
81-
int nfs3_setxattr(struct dentry *dentry, const char *name,
82-
const void *value, size_t size, int flags)
83-
{
84-
struct inode *inode = dentry->d_inode;
85-
struct posix_acl *acl;
86-
int type, error;
87-
88-
if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
89-
type = ACL_TYPE_ACCESS;
90-
else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
91-
type = ACL_TYPE_DEFAULT;
92-
else
93-
return -EOPNOTSUPP;
94-
95-
acl = posix_acl_from_xattr(&init_user_ns, value, size);
96-
if (IS_ERR(acl))
97-
return PTR_ERR(acl);
98-
error = nfs3_proc_setacl(inode, type, acl);
99-
posix_acl_release(acl);
100-
101-
return error;
102-
}
103-
104-
int nfs3_removexattr(struct dentry *dentry, const char *name)
105-
{
106-
struct inode *inode = dentry->d_inode;
107-
int type;
108-
109-
if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
110-
type = ACL_TYPE_ACCESS;
111-
else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
112-
type = ACL_TYPE_DEFAULT;
113-
else
114-
return -EOPNOTSUPP;
115-
116-
return nfs3_proc_setacl(inode, type, NULL);
117-
}
118-
119-
static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi)
120-
{
121-
if (!IS_ERR(nfsi->acl_access)) {
122-
posix_acl_release(nfsi->acl_access);
123-
nfsi->acl_access = ERR_PTR(-EAGAIN);
124-
}
125-
if (!IS_ERR(nfsi->acl_default)) {
126-
posix_acl_release(nfsi->acl_default);
127-
nfsi->acl_default = ERR_PTR(-EAGAIN);
128-
}
129-
}
130-
131-
void nfs3_forget_cached_acls(struct inode *inode)
132-
{
133-
dprintk("NFS: nfs3_forget_cached_acls(%s/%ld)\n", inode->i_sb->s_id,
134-
inode->i_ino);
135-
spin_lock(&inode->i_lock);
136-
__nfs3_forget_cached_acls(NFS_I(inode));
137-
spin_unlock(&inode->i_lock);
138-
}
139-
140-
static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type)
141-
{
142-
struct nfs_inode *nfsi = NFS_I(inode);
143-
struct posix_acl *acl = ERR_PTR(-EINVAL);
144-
145-
spin_lock(&inode->i_lock);
146-
switch(type) {
147-
case ACL_TYPE_ACCESS:
148-
acl = nfsi->acl_access;
149-
break;
150-
151-
case ACL_TYPE_DEFAULT:
152-
acl = nfsi->acl_default;
153-
break;
154-
155-
default:
156-
goto out;
157-
}
158-
if (IS_ERR(acl))
159-
acl = ERR_PTR(-EAGAIN);
160-
else
161-
acl = posix_acl_dup(acl);
162-
out:
163-
spin_unlock(&inode->i_lock);
164-
dprintk("NFS: nfs3_get_cached_acl(%s/%ld, %d) = %p\n", inode->i_sb->s_id,
165-
inode->i_ino, type, acl);
166-
return acl;
167-
}
168-
169-
static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
170-
struct posix_acl *dfacl)
171-
{
172-
struct nfs_inode *nfsi = NFS_I(inode);
173-
174-
dprintk("nfs3_cache_acls(%s/%ld, %p, %p)\n", inode->i_sb->s_id,
175-
inode->i_ino, acl, dfacl);
176-
spin_lock(&inode->i_lock);
177-
__nfs3_forget_cached_acls(NFS_I(inode));
178-
if (!IS_ERR(acl))
179-
nfsi->acl_access = posix_acl_dup(acl);
180-
if (!IS_ERR(dfacl))
181-
nfsi->acl_default = posix_acl_dup(dfacl);
182-
spin_unlock(&inode->i_lock);
183-
}
184-
185-
struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
13+
struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
18614
{
18715
struct nfs_server *server = NFS_SERVER(inode);
18816
struct page *pages[NFSACL_MAXPAGES] = { };
@@ -198,7 +26,6 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
19826
.rpc_argp = &args,
19927
.rpc_resp = &res,
20028
};
201-
struct posix_acl *acl;
20229
int status, count;
20330

20431
if (!nfs_server_capable(inode, NFS_CAP_ACLS))
@@ -207,10 +34,6 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
20734
status = nfs_revalidate_inode(server, inode);
20835
if (status < 0)
20936
return ERR_PTR(status);
210-
acl = nfs3_get_cached_acl(inode, type);
211-
if (acl != ERR_PTR(-EAGAIN))
212-
return acl;
213-
acl = NULL;
21437

21538
/*
21639
* Only get the access acl when explicitly requested: We don't
@@ -257,40 +80,41 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
25780
}
25881

25982
if (res.acl_access != NULL) {
260-
if (posix_acl_equiv_mode(res.acl_access, NULL) == 0) {
83+
if (posix_acl_equiv_mode(res.acl_access, NULL) ||
84+
res.acl_access->a_count == 0) {
26185
posix_acl_release(res.acl_access);
26286
res.acl_access = NULL;
26387
}
26488
}
265-
nfs3_cache_acls(inode,
266-
(res.mask & NFS_ACL) ? res.acl_access : ERR_PTR(-EINVAL),
267-
(res.mask & NFS_DFACL) ? res.acl_default : ERR_PTR(-EINVAL));
26889

269-
switch(type) {
270-
case ACL_TYPE_ACCESS:
271-
acl = res.acl_access;
272-
res.acl_access = NULL;
273-
break;
90+
if (res.mask & NFS_ACL)
91+
set_cached_acl(inode, ACL_TYPE_ACCESS, res.acl_access);
92+
else
93+
forget_cached_acl(inode, ACL_TYPE_ACCESS);
27494

275-
case ACL_TYPE_DEFAULT:
276-
acl = res.acl_default;
277-
res.acl_default = NULL;
95+
if (res.mask & NFS_DFACL)
96+
set_cached_acl(inode, ACL_TYPE_DEFAULT, res.acl_default);
97+
else
98+
forget_cached_acl(inode, ACL_TYPE_DEFAULT);
99+
100+
nfs_free_fattr(res.fattr);
101+
if (type == ACL_TYPE_ACCESS) {
102+
posix_acl_release(res.acl_default);
103+
return res.acl_access;
104+
} else {
105+
posix_acl_release(res.acl_access);
106+
return res.acl_default;
278107
}
279108

280109
getout:
281110
posix_acl_release(res.acl_access);
282111
posix_acl_release(res.acl_default);
283112
nfs_free_fattr(res.fattr);
284-
285-
if (status != 0) {
286-
posix_acl_release(acl);
287-
acl = ERR_PTR(status);
288-
}
289-
return acl;
113+
return ERR_PTR(status);
290114
}
291115

292-
static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
293-
struct posix_acl *dfacl)
116+
int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
117+
struct posix_acl *dfacl)
294118
{
295119
struct nfs_server *server = NFS_SERVER(inode);
296120
struct nfs_fattr *fattr;
@@ -353,7 +177,8 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
353177
switch (status) {
354178
case 0:
355179
status = nfs_refresh_inode(inode, fattr);
356-
nfs3_cache_acls(inode, acl, dfacl);
180+
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
181+
set_cached_acl(inode, ACL_TYPE_DEFAULT, dfacl);
357182
break;
358183
case -EPFNOSUPPORT:
359184
case -EPROTONOSUPPORT:
@@ -373,33 +198,27 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
373198
return status;
374199
}
375200

376-
int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
201+
int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type)
377202
{
378203
struct posix_acl *alloc = NULL, *dfacl = NULL;
379204
int status;
380205

381206
if (S_ISDIR(inode->i_mode)) {
382207
switch(type) {
383-
case ACL_TYPE_ACCESS:
384-
alloc = dfacl = nfs3_proc_getacl(inode,
385-
ACL_TYPE_DEFAULT);
386-
if (IS_ERR(alloc))
387-
goto fail;
388-
break;
389-
390-
case ACL_TYPE_DEFAULT:
391-
dfacl = acl;
392-
alloc = acl = nfs3_proc_getacl(inode,
393-
ACL_TYPE_ACCESS);
394-
if (IS_ERR(alloc))
395-
goto fail;
396-
break;
397-
398-
default:
399-
return -EINVAL;
208+
case ACL_TYPE_ACCESS:
209+
alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT);
210+
if (IS_ERR(alloc))
211+
goto fail;
212+
break;
213+
214+
case ACL_TYPE_DEFAULT:
215+
dfacl = acl;
216+
alloc = acl = get_acl(inode, ACL_TYPE_ACCESS);
217+
if (IS_ERR(alloc))
218+
goto fail;
219+
break;
400220
}
401-
} else if (type != ACL_TYPE_ACCESS)
402-
return -EINVAL;
221+
}
403222

404223
if (acl == NULL) {
405224
alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
@@ -417,24 +236,24 @@ int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
417236
int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
418237
umode_t mode)
419238
{
420-
struct posix_acl *dfacl, *acl;
421-
int error = 0;
239+
struct posix_acl *default_acl, *acl;
240+
int error;
422241

423-
dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT);
424-
if (IS_ERR(dfacl)) {
425-
error = PTR_ERR(dfacl);
242+
error = posix_acl_create(dir, &mode, &default_acl, &acl);
243+
if (error)
426244
return (error == -EOPNOTSUPP) ? 0 : error;
427-
}
428-
if (!dfacl)
429-
return 0;
430-
acl = posix_acl_dup(dfacl);
431-
error = __posix_acl_create(&acl, GFP_KERNEL, &mode);
432-
if (error < 0)
433-
goto out_release_dfacl;
434-
error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ?
435-
dfacl : NULL);
436-
posix_acl_release(acl);
437-
out_release_dfacl:
438-
posix_acl_release(dfacl);
245+
246+
error = nfs3_proc_setacls(inode, acl, default_acl);
247+
248+
if (acl)
249+
posix_acl_release(acl);
250+
if (default_acl)
251+
posix_acl_release(default_acl);
439252
return error;
440253
}
254+
255+
const struct xattr_handler *nfs3_xattr_handlers[] = {
256+
&posix_acl_access_xattr_handler,
257+
&posix_acl_default_xattr_handler,
258+
NULL,
259+
};

0 commit comments

Comments
 (0)