Skip to content

Commit e01580b

Browse files
Christoph HellwigAl Viro
authored andcommitted
gfs2: use generic posix ACL infrastructure
This contains some major refactoring for the create path so that inodes are created with the right mode to start with instead of fixing it up later. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 2cc6a5a commit e01580b

File tree

4 files changed

+62
-214
lines changed

4 files changed

+62
-214
lines changed

fs/gfs2/acl.c

Lines changed: 30 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
4949
if (!ip->i_eattr)
5050
return NULL;
5151

52-
acl = get_cached_acl(&ip->i_inode, type);
53-
if (acl != ACL_NOT_CACHED)
54-
return acl;
55-
5652
name = gfs2_acl_name(type);
5753
if (name == NULL)
5854
return ERR_PTR(-EINVAL);
@@ -80,227 +76,57 @@ static int gfs2_set_mode(struct inode *inode, umode_t mode)
8076
return error;
8177
}
8278

83-
static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl)
79+
int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
8480
{
8581
int error;
8682
int len;
8783
char *data;
8884
const char *name = gfs2_acl_name(type);
8985

9086
BUG_ON(name == NULL);
91-
len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
92-
if (len == 0)
93-
return 0;
94-
data = kmalloc(len, GFP_NOFS);
95-
if (data == NULL)
96-
return -ENOMEM;
97-
error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
98-
if (error < 0)
99-
goto out;
100-
error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
101-
if (!error)
102-
set_cached_acl(inode, type, acl);
103-
out:
104-
kfree(data);
105-
return error;
106-
}
107-
108-
int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode)
109-
{
110-
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
111-
struct posix_acl *acl;
112-
umode_t mode = inode->i_mode;
113-
int error = 0;
114-
115-
if (!sdp->sd_args.ar_posix_acl)
116-
return 0;
117-
if (S_ISLNK(inode->i_mode))
118-
return 0;
119-
120-
acl = gfs2_get_acl(&dip->i_inode, ACL_TYPE_DEFAULT);
121-
if (IS_ERR(acl))
122-
return PTR_ERR(acl);
123-
if (!acl) {
124-
mode &= ~current_umask();
125-
return gfs2_set_mode(inode, mode);
126-
}
127-
128-
if (S_ISDIR(inode->i_mode)) {
129-
error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl);
130-
if (error)
131-
goto out;
132-
}
133-
134-
error = __posix_acl_create(&acl, GFP_NOFS, &mode);
135-
if (error < 0)
136-
return error;
13787

138-
if (error == 0)
139-
goto munge;
140-
141-
error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl);
142-
if (error)
143-
goto out;
144-
munge:
145-
error = gfs2_set_mode(inode, mode);
146-
out:
147-
posix_acl_release(acl);
148-
return error;
149-
}
150-
151-
int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
152-
{
153-
struct inode *inode = &ip->i_inode;
154-
struct posix_acl *acl;
155-
char *data;
156-
unsigned int len;
157-
int error;
158-
159-
acl = gfs2_get_acl(&ip->i_inode, ACL_TYPE_ACCESS);
160-
if (IS_ERR(acl))
161-
return PTR_ERR(acl);
162-
if (!acl)
163-
return gfs2_setattr_simple(inode, attr);
164-
165-
error = __posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode);
166-
if (error)
167-
return error;
168-
169-
len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
170-
data = kmalloc(len, GFP_NOFS);
171-
error = -ENOMEM;
172-
if (data == NULL)
173-
goto out;
174-
posix_acl_to_xattr(&init_user_ns, acl, data, len);
175-
error = gfs2_xattr_acl_chmod(ip, attr, data);
176-
kfree(data);
177-
set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl);
178-
179-
out:
180-
posix_acl_release(acl);
181-
return error;
182-
}
183-
184-
static int gfs2_acl_type(const char *name)
185-
{
186-
if (strcmp(name, GFS2_POSIX_ACL_ACCESS) == 0)
187-
return ACL_TYPE_ACCESS;
188-
if (strcmp(name, GFS2_POSIX_ACL_DEFAULT) == 0)
189-
return ACL_TYPE_DEFAULT;
190-
return -EINVAL;
191-
}
192-
193-
static int gfs2_xattr_system_get(struct dentry *dentry, const char *name,
194-
void *buffer, size_t size, int xtype)
195-
{
196-
struct inode *inode = dentry->d_inode;
197-
struct gfs2_sbd *sdp = GFS2_SB(inode);
198-
struct posix_acl *acl;
199-
int type;
200-
int error;
201-
202-
if (!sdp->sd_args.ar_posix_acl)
203-
return -EOPNOTSUPP;
204-
205-
type = gfs2_acl_type(name);
206-
if (type < 0)
207-
return type;
208-
209-
acl = gfs2_get_acl(inode, type);
210-
if (IS_ERR(acl))
211-
return PTR_ERR(acl);
212-
if (acl == NULL)
213-
return -ENODATA;
214-
215-
error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
216-
posix_acl_release(acl);
217-
218-
return error;
219-
}
220-
221-
static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,
222-
const void *value, size_t size, int flags,
223-
int xtype)
224-
{
225-
struct inode *inode = dentry->d_inode;
226-
struct gfs2_sbd *sdp = GFS2_SB(inode);
227-
struct posix_acl *acl = NULL;
228-
int error = 0, type;
229-
230-
if (!sdp->sd_args.ar_posix_acl)
231-
return -EOPNOTSUPP;
232-
233-
type = gfs2_acl_type(name);
234-
if (type < 0)
235-
return type;
236-
if (flags & XATTR_CREATE)
237-
return -EINVAL;
238-
if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
239-
return value ? -EACCES : 0;
240-
if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_FOWNER))
241-
return -EPERM;
242-
if (S_ISLNK(inode->i_mode))
243-
return -EOPNOTSUPP;
244-
245-
if (!value)
246-
goto set_acl;
247-
248-
acl = posix_acl_from_xattr(&init_user_ns, value, size);
249-
if (!acl) {
250-
/*
251-
* acl_set_file(3) may request that we set default ACLs with
252-
* zero length -- defend (gracefully) against that here.
253-
*/
254-
goto out;
255-
}
256-
if (IS_ERR(acl)) {
257-
error = PTR_ERR(acl);
258-
goto out;
259-
}
260-
261-
error = posix_acl_valid(acl);
262-
if (error)
263-
goto out_release;
264-
265-
error = -EINVAL;
26688
if (acl->a_count > GFS2_ACL_MAX_ENTRIES)
267-
goto out_release;
89+
return -EINVAL;
26890

26991
if (type == ACL_TYPE_ACCESS) {
27092
umode_t mode = inode->i_mode;
93+
27194
error = posix_acl_equiv_mode(acl, &mode);
95+
if (error < 0)
96+
return error;
27297

273-
if (error <= 0) {
274-
posix_acl_release(acl);
98+
if (error == 0)
27599
acl = NULL;
276100

277-
if (error < 0)
278-
return error;
279-
}
280-
281101
error = gfs2_set_mode(inode, mode);
282102
if (error)
283-
goto out_release;
103+
return error;
284104
}
285105

286-
set_acl:
287-
error = __gfs2_xattr_set(inode, name, value, size, 0, GFS2_EATYPE_SYS);
288-
if (!error) {
289-
if (acl)
290-
set_cached_acl(inode, type, acl);
291-
else
292-
forget_cached_acl(inode, type);
106+
if (acl) {
107+
len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
108+
if (len == 0)
109+
return 0;
110+
data = kmalloc(len, GFP_NOFS);
111+
if (data == NULL)
112+
return -ENOMEM;
113+
error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
114+
if (error < 0)
115+
goto out;
116+
} else {
117+
data = NULL;
118+
len = 0;
293119
}
294-
out_release:
295-
posix_acl_release(acl);
120+
121+
error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
122+
if (error)
123+
goto out;
124+
125+
if (acl)
126+
set_cached_acl(inode, type, acl);
127+
else
128+
forget_cached_acl(inode, type);
296129
out:
130+
kfree(data);
297131
return error;
298132
}
299-
300-
const struct xattr_handler gfs2_xattr_system_handler = {
301-
.prefix = XATTR_SYSTEM_PREFIX,
302-
.flags = GFS2_EATYPE_SYS,
303-
.get = gfs2_xattr_system_get,
304-
.set = gfs2_xattr_system_set,
305-
};
306-

fs/gfs2/acl.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#define GFS2_ACL_MAX_ENTRIES 25
1818

1919
extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type);
20-
extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode);
21-
extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
22-
extern const struct xattr_handler gfs2_xattr_system_handler;
20+
extern int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
2321

2422
#endif /* __ACL_DOT_H__ */

fs/gfs2/inode.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
552552
unsigned int size, int excl, int *opened)
553553
{
554554
const struct qstr *name = &dentry->d_name;
555+
struct posix_acl *default_acl, *acl;
555556
struct gfs2_holder ghs[2];
556557
struct inode *inode = NULL;
557558
struct gfs2_inode *dip = GFS2_I(dir), *ip;
@@ -611,10 +612,14 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
611612
if (!inode)
612613
goto fail_gunlock;
613614

615+
error = posix_acl_create(dir, &mode, &default_acl, &acl);
616+
if (error)
617+
goto fail_free_vfs_inode;
618+
614619
ip = GFS2_I(inode);
615620
error = gfs2_rs_alloc(ip);
616621
if (error)
617-
goto fail_free_inode;
622+
goto fail_free_acls;
618623

619624
inode->i_mode = mode;
620625
set_nlink(inode, S_ISDIR(mode) ? 2 : 1);
@@ -682,7 +687,16 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
682687
gfs2_set_iop(inode);
683688
insert_inode_hash(inode);
684689

685-
error = gfs2_acl_create(dip, inode);
690+
if (default_acl) {
691+
error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
692+
posix_acl_release(default_acl);
693+
}
694+
if (acl) {
695+
if (!error)
696+
error = gfs2_set_acl(inode, acl, ACL_TYPE_ACCESS);
697+
posix_acl_release(acl);
698+
}
699+
686700
if (error)
687701
goto fail_gunlock3;
688702

@@ -716,6 +730,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
716730
if (ip->i_gl)
717731
gfs2_glock_put(ip->i_gl);
718732
gfs2_rs_delete(ip, NULL);
733+
fail_free_acls:
734+
if (default_acl)
735+
posix_acl_release(default_acl);
736+
if (acl)
737+
posix_acl_release(acl);
738+
fail_free_vfs_inode:
719739
free_inode_nonrcu(inode);
720740
inode = NULL;
721741
fail_gunlock:
@@ -1678,10 +1698,11 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
16781698
error = gfs2_setattr_size(inode, attr->ia_size);
16791699
else if (attr->ia_valid & (ATTR_UID | ATTR_GID))
16801700
error = setattr_chown(inode, attr);
1681-
else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode))
1682-
error = gfs2_acl_chmod(ip, attr);
1683-
else
1701+
else {
16841702
error = gfs2_setattr_simple(inode, attr);
1703+
if (!error && attr->ia_valid & ATTR_MODE)
1704+
error = posix_acl_chmod(inode, inode->i_mode);
1705+
}
16851706

16861707
out:
16871708
if (!error)
@@ -1841,6 +1862,7 @@ const struct inode_operations gfs2_file_iops = {
18411862
.removexattr = gfs2_removexattr,
18421863
.fiemap = gfs2_fiemap,
18431864
.get_acl = gfs2_get_acl,
1865+
.set_acl = gfs2_set_acl,
18441866
};
18451867

18461868
const struct inode_operations gfs2_dir_iops = {
@@ -1862,6 +1884,7 @@ const struct inode_operations gfs2_dir_iops = {
18621884
.removexattr = gfs2_removexattr,
18631885
.fiemap = gfs2_fiemap,
18641886
.get_acl = gfs2_get_acl,
1887+
.set_acl = gfs2_set_acl,
18651888
.atomic_open = gfs2_atomic_open,
18661889
};
18671890

@@ -1877,6 +1900,5 @@ const struct inode_operations gfs2_symlink_iops = {
18771900
.listxattr = gfs2_listxattr,
18781901
.removexattr = gfs2_removexattr,
18791902
.fiemap = gfs2_fiemap,
1880-
.get_acl = gfs2_get_acl,
18811903
};
18821904

fs/gfs2/xattr.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/buffer_head.h>
1414
#include <linux/xattr.h>
1515
#include <linux/gfs2_ondisk.h>
16+
#include <linux/posix_acl_xattr.h>
1617
#include <asm/uaccess.h>
1718

1819
#include "gfs2.h"
@@ -1500,7 +1501,8 @@ static const struct xattr_handler gfs2_xattr_security_handler = {
15001501
const struct xattr_handler *gfs2_xattr_handlers[] = {
15011502
&gfs2_xattr_user_handler,
15021503
&gfs2_xattr_security_handler,
1503-
&gfs2_xattr_system_handler,
1504+
&posix_acl_access_xattr_handler,
1505+
&posix_acl_default_xattr_handler,
15041506
NULL,
15051507
};
15061508

0 commit comments

Comments
 (0)