aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/acl.c170
-rw-r--r--fs/gfs2/acl.h24
-rw-r--r--fs/gfs2/xattr.c18
3 files changed, 120 insertions, 92 deletions
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 3fc4e3ac7d84..2168da121647 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -12,6 +12,7 @@
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/xattr.h>
15#include <linux/posix_acl.h> 16#include <linux/posix_acl.h>
16#include <linux/posix_acl_xattr.h> 17#include <linux/posix_acl_xattr.h>
17#include <linux/gfs2_ondisk.h> 18#include <linux/gfs2_ondisk.h>
@@ -26,61 +27,6 @@
26#include "trans.h" 27#include "trans.h"
27#include "util.h" 28#include "util.h"
28 29
29#define ACL_ACCESS 1
30#define ACL_DEFAULT 0
31
32int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
33 struct gfs2_ea_request *er, int *remove, mode_t *mode)
34{
35 struct posix_acl *acl;
36 int error;
37
38 error = gfs2_acl_validate_remove(ip, access);
39 if (error)
40 return error;
41
42 if (!er->er_data)
43 return -EINVAL;
44
45 acl = posix_acl_from_xattr(er->er_data, er->er_data_len);
46 if (IS_ERR(acl))
47 return PTR_ERR(acl);
48 if (!acl) {
49 *remove = 1;
50 return 0;
51 }
52
53 error = posix_acl_valid(acl);
54 if (error)
55 goto out;
56
57 if (access) {
58 error = posix_acl_equiv_mode(acl, mode);
59 if (!error)
60 *remove = 1;
61 else if (error > 0)
62 error = 0;
63 }
64
65out:
66 posix_acl_release(acl);
67 return error;
68}
69
70int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
71{
72 if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
73 return -EOPNOTSUPP;
74 if (!is_owner_or_cap(&ip->i_inode))
75 return -EPERM;
76 if (S_ISLNK(ip->i_inode.i_mode))
77 return -EOPNOTSUPP;
78 if (!access && !S_ISDIR(ip->i_inode.i_mode))
79 return -EACCES;
80
81 return 0;
82}
83
84static int acl_get(struct gfs2_inode *ip, const char *name, 30static int acl_get(struct gfs2_inode *ip, const char *name,
85 struct posix_acl **acl, struct gfs2_ea_location *el, 31 struct posix_acl **acl, struct gfs2_ea_location *el,
86 char **datap, unsigned int *lenp) 32 char **datap, unsigned int *lenp)
@@ -277,3 +223,117 @@ out_brelse:
277 return error; 223 return error;
278} 224}
279 225
226static int gfs2_acl_type(const char *name)
227{
228 if (strcmp(name, GFS2_POSIX_ACL_ACCESS) == 0)
229 return ACL_TYPE_ACCESS;
230 if (strcmp(name, GFS2_POSIX_ACL_DEFAULT) == 0)
231 return ACL_TYPE_DEFAULT;
232 return -EINVAL;
233}
234
235static int gfs2_xattr_system_get(struct inode *inode, const char *name,
236 void *buffer, size_t size)
237{
238 int type;
239
240 type = gfs2_acl_type(name);
241 if (type < 0)
242 return type;
243
244 return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
245}
246
247static int gfs2_set_mode(struct inode *inode, mode_t mode)
248{
249 int error = 0;
250
251 if (mode != inode->i_mode) {
252 struct iattr iattr;
253
254 iattr.ia_valid = ATTR_MODE;
255 iattr.ia_mode = mode;
256
257 error = gfs2_setattr_simple(GFS2_I(inode), &iattr);
258 }
259
260 return error;
261}
262
263static int gfs2_xattr_system_set(struct inode *inode, const char *name,
264 const void *value, size_t size, int flags)
265{
266 struct gfs2_sbd *sdp = GFS2_SB(inode);
267 struct posix_acl *acl = NULL;
268 int error = 0, type;
269
270 if (!sdp->sd_args.ar_posix_acl)
271 return -EOPNOTSUPP;
272
273 type = gfs2_acl_type(name);
274 if (type < 0)
275 return type;
276 if (flags & XATTR_CREATE)
277 return -EINVAL;
278 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
279 return value ? -EACCES : 0;
280 if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
281 return -EPERM;
282 if (S_ISLNK(inode->i_mode))
283 return -EOPNOTSUPP;
284
285 if (!value)
286 goto set_acl;
287
288 acl = posix_acl_from_xattr(value, size);
289 if (!acl) {
290 /*
291 * acl_set_file(3) may request that we set default ACLs with
292 * zero length -- defend (gracefully) against that here.
293 */
294 goto out;
295 }
296 if (IS_ERR(acl)) {
297 error = PTR_ERR(acl);
298 goto out;
299 }
300
301 error = posix_acl_valid(acl);
302 if (error)
303 goto out_release;
304
305 error = -EINVAL;
306 if (acl->a_count > GFS2_ACL_MAX_ENTRIES)
307 goto out_release;
308
309 if (type == ACL_TYPE_ACCESS) {
310 mode_t mode = inode->i_mode;
311 error = posix_acl_equiv_mode(acl, &mode);
312
313 if (error <= 0) {
314 posix_acl_release(acl);
315 acl = NULL;
316
317 if (error < 0)
318 return error;
319 }
320
321 error = gfs2_set_mode(inode, mode);
322 if (error)
323 goto out_release;
324 }
325
326set_acl:
327 error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, 0);
328out_release:
329 posix_acl_release(acl);
330out:
331 return error;
332}
333
334struct xattr_handler gfs2_xattr_system_handler = {
335 .prefix = XATTR_SYSTEM_PREFIX,
336 .get = gfs2_xattr_system_get,
337 .set = gfs2_xattr_system_set,
338};
339
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h
index 6751930bfb64..cc954390b6da 100644
--- a/fs/gfs2/acl.h
+++ b/fs/gfs2/acl.h
@@ -13,26 +13,12 @@
13#include "incore.h" 13#include "incore.h"
14 14
15#define GFS2_POSIX_ACL_ACCESS "posix_acl_access" 15#define GFS2_POSIX_ACL_ACCESS "posix_acl_access"
16#define GFS2_POSIX_ACL_ACCESS_LEN 16
17#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default" 16#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default"
18#define GFS2_POSIX_ACL_DEFAULT_LEN 17 17#define GFS2_ACL_MAX_ENTRIES 25
19 18
20#define GFS2_ACL_IS_ACCESS(name, len) \ 19extern int gfs2_check_acl(struct inode *inode, int mask);
21 ((len) == GFS2_POSIX_ACL_ACCESS_LEN && \ 20extern int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip);
22 !memcmp(GFS2_POSIX_ACL_ACCESS, (name), (len))) 21extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
23 22extern struct xattr_handler gfs2_xattr_system_handler;
24#define GFS2_ACL_IS_DEFAULT(name, len) \
25 ((len) == GFS2_POSIX_ACL_DEFAULT_LEN && \
26 !memcmp(GFS2_POSIX_ACL_DEFAULT, (name), (len)))
27
28struct gfs2_ea_request;
29
30int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
31 struct gfs2_ea_request *er,
32 int *remove, mode_t *mode);
33int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access);
34int gfs2_check_acl(struct inode *inode, int mask);
35int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip);
36int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
37 23
38#endif /* __ACL_DOT_H__ */ 24#endif /* __ACL_DOT_H__ */
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 8a0f8ef6ee27..6b803540951e 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -1507,18 +1507,6 @@ static int gfs2_xattr_user_set(struct inode *inode, const char *name,
1507 return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags); 1507 return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags);
1508} 1508}
1509 1509
1510static int gfs2_xattr_system_get(struct inode *inode, const char *name,
1511 void *buffer, size_t size)
1512{
1513 return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
1514}
1515
1516static int gfs2_xattr_system_set(struct inode *inode, const char *name,
1517 const void *value, size_t size, int flags)
1518{
1519 return gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, flags);
1520}
1521
1522static int gfs2_xattr_security_get(struct inode *inode, const char *name, 1510static int gfs2_xattr_security_get(struct inode *inode, const char *name,
1523 void *buffer, size_t size) 1511 void *buffer, size_t size)
1524{ 1512{
@@ -1543,12 +1531,6 @@ static struct xattr_handler gfs2_xattr_security_handler = {
1543 .set = gfs2_xattr_security_set, 1531 .set = gfs2_xattr_security_set,
1544}; 1532};
1545 1533
1546static struct xattr_handler gfs2_xattr_system_handler = {
1547 .prefix = XATTR_SYSTEM_PREFIX,
1548 .get = gfs2_xattr_system_get,
1549 .set = gfs2_xattr_system_set,
1550};
1551
1552struct xattr_handler *gfs2_xattr_handlers[] = { 1534struct xattr_handler *gfs2_xattr_handlers[] = {
1553 &gfs2_xattr_user_handler, 1535 &gfs2_xattr_user_handler,
1554 &gfs2_xattr_security_handler, 1536 &gfs2_xattr_security_handler,