diff options
author | Vyacheslav Dubeyko <slava@dubeyko.com> | 2013-09-11 17:24:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-11 18:59:01 -0400 |
commit | b4c1107cc962613ea3572e5abba861a35d494b98 (patch) | |
tree | 9e83d6f00b37cb65a8e2f2ef435bead7b662c10f /fs/hfsplus | |
parent | eef80d4ad1399067f26538a7dd56ff3df71e9278 (diff) |
hfsplus: integrate POSIX ACLs support into driver
Integrate implemented POSIX ACLs support into hfsplus driver.
Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Hin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/hfsplus')
-rw-r--r-- | fs/hfsplus/Makefile | 2 | ||||
-rw-r--r-- | fs/hfsplus/dir.c | 4 | ||||
-rw-r--r-- | fs/hfsplus/inode.c | 11 | ||||
-rw-r--r-- | fs/hfsplus/xattr.c | 62 | ||||
-rw-r--r-- | fs/hfsplus/xattr.h | 33 | ||||
-rw-r--r-- | fs/hfsplus/xattr_security.c | 13 |
6 files changed, 99 insertions, 26 deletions
diff --git a/fs/hfsplus/Makefile b/fs/hfsplus/Makefile index 09d278bb7b91..683fca2e5e65 100644 --- a/fs/hfsplus/Makefile +++ b/fs/hfsplus/Makefile | |||
@@ -7,3 +7,5 @@ obj-$(CONFIG_HFSPLUS_FS) += hfsplus.o | |||
7 | hfsplus-objs := super.o options.o inode.o ioctl.o extents.o catalog.o dir.o btree.o \ | 7 | hfsplus-objs := super.o options.o inode.o ioctl.o extents.o catalog.o dir.o btree.o \ |
8 | bnode.o brec.o bfind.o tables.o unicode.o wrapper.o bitmap.o part_tbl.o \ | 8 | bnode.o brec.o bfind.o tables.o unicode.o wrapper.o bitmap.o part_tbl.o \ |
9 | attributes.o xattr.o xattr_user.o xattr_security.o xattr_trusted.o | 9 | attributes.o xattr.o xattr_user.o xattr_security.o xattr_trusted.o |
10 | |||
11 | hfsplus-$(CONFIG_HFSPLUS_FS_POSIX_ACL) += posix_acl.o | ||
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index d8ce4bd17fc5..4a4fea002673 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "hfsplus_fs.h" | 16 | #include "hfsplus_fs.h" |
17 | #include "hfsplus_raw.h" | 17 | #include "hfsplus_raw.h" |
18 | #include "xattr.h" | 18 | #include "xattr.h" |
19 | #include "acl.h" | ||
19 | 20 | ||
20 | static inline void hfsplus_instantiate(struct dentry *dentry, | 21 | static inline void hfsplus_instantiate(struct dentry *dentry, |
21 | struct inode *inode, u32 cnid) | 22 | struct inode *inode, u32 cnid) |
@@ -529,6 +530,9 @@ const struct inode_operations hfsplus_dir_inode_operations = { | |||
529 | .getxattr = generic_getxattr, | 530 | .getxattr = generic_getxattr, |
530 | .listxattr = hfsplus_listxattr, | 531 | .listxattr = hfsplus_listxattr, |
531 | .removexattr = hfsplus_removexattr, | 532 | .removexattr = hfsplus_removexattr, |
533 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL | ||
534 | .get_acl = hfsplus_get_posix_acl, | ||
535 | #endif | ||
532 | }; | 536 | }; |
533 | 537 | ||
534 | const struct file_operations hfsplus_dir_operations = { | 538 | const struct file_operations hfsplus_dir_operations = { |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index f833d35630ab..4d2edaea891c 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include "hfsplus_fs.h" | 19 | #include "hfsplus_fs.h" |
20 | #include "hfsplus_raw.h" | 20 | #include "hfsplus_raw.h" |
21 | #include "xattr.h" | 21 | #include "xattr.h" |
22 | #include "acl.h" | ||
22 | 23 | ||
23 | static int hfsplus_readpage(struct file *file, struct page *page) | 24 | static int hfsplus_readpage(struct file *file, struct page *page) |
24 | { | 25 | { |
@@ -316,6 +317,13 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) | |||
316 | 317 | ||
317 | setattr_copy(inode, attr); | 318 | setattr_copy(inode, attr); |
318 | mark_inode_dirty(inode); | 319 | mark_inode_dirty(inode); |
320 | |||
321 | if (attr->ia_valid & ATTR_MODE) { | ||
322 | error = hfsplus_posix_acl_chmod(inode); | ||
323 | if (unlikely(error)) | ||
324 | return error; | ||
325 | } | ||
326 | |||
319 | return 0; | 327 | return 0; |
320 | } | 328 | } |
321 | 329 | ||
@@ -383,6 +391,9 @@ static const struct inode_operations hfsplus_file_inode_operations = { | |||
383 | .getxattr = generic_getxattr, | 391 | .getxattr = generic_getxattr, |
384 | .listxattr = hfsplus_listxattr, | 392 | .listxattr = hfsplus_listxattr, |
385 | .removexattr = hfsplus_removexattr, | 393 | .removexattr = hfsplus_removexattr, |
394 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL | ||
395 | .get_acl = hfsplus_get_posix_acl, | ||
396 | #endif | ||
386 | }; | 397 | }; |
387 | 398 | ||
388 | static const struct file_operations hfsplus_file_operations = { | 399 | static const struct file_operations hfsplus_file_operations = { |
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index f66346155df5..bd8471fb9a6a 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c | |||
@@ -8,11 +8,16 @@ | |||
8 | 8 | ||
9 | #include "hfsplus_fs.h" | 9 | #include "hfsplus_fs.h" |
10 | #include "xattr.h" | 10 | #include "xattr.h" |
11 | #include "acl.h" | ||
11 | 12 | ||
12 | const struct xattr_handler *hfsplus_xattr_handlers[] = { | 13 | const struct xattr_handler *hfsplus_xattr_handlers[] = { |
13 | &hfsplus_xattr_osx_handler, | 14 | &hfsplus_xattr_osx_handler, |
14 | &hfsplus_xattr_user_handler, | 15 | &hfsplus_xattr_user_handler, |
15 | &hfsplus_xattr_trusted_handler, | 16 | &hfsplus_xattr_trusted_handler, |
17 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL | ||
18 | &hfsplus_xattr_acl_access_handler, | ||
19 | &hfsplus_xattr_acl_default_handler, | ||
20 | #endif | ||
16 | &hfsplus_xattr_security_handler, | 21 | &hfsplus_xattr_security_handler, |
17 | NULL | 22 | NULL |
18 | }; | 23 | }; |
@@ -46,11 +51,58 @@ static inline int is_known_namespace(const char *name) | |||
46 | return true; | 51 | return true; |
47 | } | 52 | } |
48 | 53 | ||
54 | static int can_set_system_xattr(struct inode *inode, const char *name, | ||
55 | const void *value, size_t size) | ||
56 | { | ||
57 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL | ||
58 | struct posix_acl *acl; | ||
59 | int err; | ||
60 | |||
61 | if (!inode_owner_or_capable(inode)) | ||
62 | return -EPERM; | ||
63 | |||
64 | /* | ||
65 | * POSIX_ACL_XATTR_ACCESS is tied to i_mode | ||
66 | */ | ||
67 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) { | ||
68 | acl = posix_acl_from_xattr(&init_user_ns, value, size); | ||
69 | if (IS_ERR(acl)) | ||
70 | return PTR_ERR(acl); | ||
71 | if (acl) { | ||
72 | err = posix_acl_equiv_mode(acl, &inode->i_mode); | ||
73 | posix_acl_release(acl); | ||
74 | if (err < 0) | ||
75 | return err; | ||
76 | mark_inode_dirty(inode); | ||
77 | } | ||
78 | /* | ||
79 | * We're changing the ACL. Get rid of the cached one | ||
80 | */ | ||
81 | forget_cached_acl(inode, ACL_TYPE_ACCESS); | ||
82 | |||
83 | return 0; | ||
84 | } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { | ||
85 | acl = posix_acl_from_xattr(&init_user_ns, value, size); | ||
86 | if (IS_ERR(acl)) | ||
87 | return PTR_ERR(acl); | ||
88 | posix_acl_release(acl); | ||
89 | |||
90 | /* | ||
91 | * We're changing the default ACL. Get rid of the cached one | ||
92 | */ | ||
93 | forget_cached_acl(inode, ACL_TYPE_DEFAULT); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | #endif /* CONFIG_HFSPLUS_FS_POSIX_ACL */ | ||
98 | return -EOPNOTSUPP; | ||
99 | } | ||
100 | |||
49 | static int can_set_xattr(struct inode *inode, const char *name, | 101 | static int can_set_xattr(struct inode *inode, const char *name, |
50 | const void *value, size_t value_len) | 102 | const void *value, size_t value_len) |
51 | { | 103 | { |
52 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | 104 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) |
53 | return -EOPNOTSUPP; /* TODO: implement ACL support */ | 105 | return can_set_system_xattr(inode, name, value, value_len); |
54 | 106 | ||
55 | if (!strncmp(name, XATTR_MAC_OSX_PREFIX, XATTR_MAC_OSX_PREFIX_LEN)) { | 107 | if (!strncmp(name, XATTR_MAC_OSX_PREFIX, XATTR_MAC_OSX_PREFIX_LEN)) { |
56 | /* | 108 | /* |
@@ -253,11 +305,10 @@ static int copy_name(char *buffer, const char *xattr_name, int name_len) | |||
253 | return len; | 305 | return len; |
254 | } | 306 | } |
255 | 307 | ||
256 | static ssize_t hfsplus_getxattr_finder_info(struct dentry *dentry, | 308 | static ssize_t hfsplus_getxattr_finder_info(struct inode *inode, |
257 | void *value, size_t size) | 309 | void *value, size_t size) |
258 | { | 310 | { |
259 | ssize_t res = 0; | 311 | ssize_t res = 0; |
260 | struct inode *inode = dentry->d_inode; | ||
261 | struct hfs_find_data fd; | 312 | struct hfs_find_data fd; |
262 | u16 entry_type; | 313 | u16 entry_type; |
263 | u16 folder_rec_len = sizeof(struct DInfo) + sizeof(struct DXInfo); | 314 | u16 folder_rec_len = sizeof(struct DInfo) + sizeof(struct DXInfo); |
@@ -304,10 +355,9 @@ end_getxattr_finder_info: | |||
304 | return res; | 355 | return res; |
305 | } | 356 | } |
306 | 357 | ||
307 | ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | 358 | ssize_t __hfsplus_getxattr(struct inode *inode, const char *name, |
308 | void *value, size_t size) | 359 | void *value, size_t size) |
309 | { | 360 | { |
310 | struct inode *inode = dentry->d_inode; | ||
311 | struct hfs_find_data fd; | 361 | struct hfs_find_data fd; |
312 | hfsplus_attr_entry *entry; | 362 | hfsplus_attr_entry *entry; |
313 | __be32 xattr_record_type; | 363 | __be32 xattr_record_type; |
@@ -333,7 +383,7 @@ ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | |||
333 | } | 383 | } |
334 | 384 | ||
335 | if (!strcmp_xattr_finder_info(name)) | 385 | if (!strcmp_xattr_finder_info(name)) |
336 | return hfsplus_getxattr_finder_info(dentry, value, size); | 386 | return hfsplus_getxattr_finder_info(inode, value, size); |
337 | 387 | ||
338 | if (!HFSPLUS_SB(inode->i_sb)->attr_tree) | 388 | if (!HFSPLUS_SB(inode->i_sb)->attr_tree) |
339 | return -EOPNOTSUPP; | 389 | return -EOPNOTSUPP; |
diff --git a/fs/hfsplus/xattr.h b/fs/hfsplus/xattr.h index 847b695b984d..841b5698c0fc 100644 --- a/fs/hfsplus/xattr.h +++ b/fs/hfsplus/xattr.h | |||
@@ -14,8 +14,8 @@ | |||
14 | extern const struct xattr_handler hfsplus_xattr_osx_handler; | 14 | extern const struct xattr_handler hfsplus_xattr_osx_handler; |
15 | extern const struct xattr_handler hfsplus_xattr_user_handler; | 15 | extern const struct xattr_handler hfsplus_xattr_user_handler; |
16 | extern const struct xattr_handler hfsplus_xattr_trusted_handler; | 16 | extern const struct xattr_handler hfsplus_xattr_trusted_handler; |
17 | /*extern const struct xattr_handler hfsplus_xattr_acl_access_handler;*/ | 17 | extern const struct xattr_handler hfsplus_xattr_acl_access_handler; |
18 | /*extern const struct xattr_handler hfsplus_xattr_acl_default_handler;*/ | 18 | extern const struct xattr_handler hfsplus_xattr_acl_default_handler; |
19 | extern const struct xattr_handler hfsplus_xattr_security_handler; | 19 | extern const struct xattr_handler hfsplus_xattr_security_handler; |
20 | 20 | ||
21 | extern const struct xattr_handler *hfsplus_xattr_handlers[]; | 21 | extern const struct xattr_handler *hfsplus_xattr_handlers[]; |
@@ -29,9 +29,17 @@ static inline int hfsplus_setxattr(struct dentry *dentry, const char *name, | |||
29 | return __hfsplus_setxattr(dentry->d_inode, name, value, size, flags); | 29 | return __hfsplus_setxattr(dentry->d_inode, name, value, size, flags); |
30 | } | 30 | } |
31 | 31 | ||
32 | ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, | 32 | ssize_t __hfsplus_getxattr(struct inode *inode, const char *name, |
33 | void *value, size_t size); | 33 | void *value, size_t size); |
34 | 34 | ||
35 | static inline ssize_t hfsplus_getxattr(struct dentry *dentry, | ||
36 | const char *name, | ||
37 | void *value, | ||
38 | size_t size) | ||
39 | { | ||
40 | return __hfsplus_getxattr(dentry->d_inode, name, value, size); | ||
41 | } | ||
42 | |||
35 | ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size); | 43 | ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size); |
36 | 44 | ||
37 | int hfsplus_removexattr(struct dentry *dentry, const char *name); | 45 | int hfsplus_removexattr(struct dentry *dentry, const char *name); |
@@ -39,22 +47,7 @@ int hfsplus_removexattr(struct dentry *dentry, const char *name); | |||
39 | int hfsplus_init_security(struct inode *inode, struct inode *dir, | 47 | int hfsplus_init_security(struct inode *inode, struct inode *dir, |
40 | const struct qstr *qstr); | 48 | const struct qstr *qstr); |
41 | 49 | ||
42 | static inline int hfsplus_init_acl(struct inode *inode, struct inode *dir) | 50 | int hfsplus_init_inode_security(struct inode *inode, struct inode *dir, |
43 | { | 51 | const struct qstr *qstr); |
44 | /*TODO: implement*/ | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static inline int hfsplus_init_inode_security(struct inode *inode, | ||
49 | struct inode *dir, | ||
50 | const struct qstr *qstr) | ||
51 | { | ||
52 | int err; | ||
53 | |||
54 | err = hfsplus_init_acl(inode, dir); | ||
55 | if (!err) | ||
56 | err = hfsplus_init_security(inode, dir, qstr); | ||
57 | return err; | ||
58 | } | ||
59 | 52 | ||
60 | #endif | 53 | #endif |
diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c index 83b842f113c5..00722765ea79 100644 --- a/fs/hfsplus/xattr_security.c +++ b/fs/hfsplus/xattr_security.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/security.h> | 9 | #include <linux/security.h> |
10 | #include "hfsplus_fs.h" | 10 | #include "hfsplus_fs.h" |
11 | #include "xattr.h" | 11 | #include "xattr.h" |
12 | #include "acl.h" | ||
12 | 13 | ||
13 | static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, | 14 | static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, |
14 | void *buffer, size_t size, int type) | 15 | void *buffer, size_t size, int type) |
@@ -96,6 +97,18 @@ int hfsplus_init_security(struct inode *inode, struct inode *dir, | |||
96 | &hfsplus_initxattrs, NULL); | 97 | &hfsplus_initxattrs, NULL); |
97 | } | 98 | } |
98 | 99 | ||
100 | int hfsplus_init_inode_security(struct inode *inode, | ||
101 | struct inode *dir, | ||
102 | const struct qstr *qstr) | ||
103 | { | ||
104 | int err; | ||
105 | |||
106 | err = hfsplus_init_posix_acl(inode, dir); | ||
107 | if (!err) | ||
108 | err = hfsplus_init_security(inode, dir, qstr); | ||
109 | return err; | ||
110 | } | ||
111 | |||
99 | const struct xattr_handler hfsplus_xattr_security_handler = { | 112 | const struct xattr_handler hfsplus_xattr_security_handler = { |
100 | .prefix = XATTR_SECURITY_PREFIX, | 113 | .prefix = XATTR_SECURITY_PREFIX, |
101 | .list = hfsplus_security_listxattr, | 114 | .list = hfsplus_security_listxattr, |