Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Vyacheslav Dubeyko and committed by
Linus Torvalds
b4c1107c eef80d4a

+99 -26
+2
fs/hfsplus/Makefile
··· 7 7 hfsplus-objs := super.o options.o inode.o ioctl.o extents.o catalog.o dir.o btree.o \ 8 8 bnode.o brec.o bfind.o tables.o unicode.o wrapper.o bitmap.o part_tbl.o \ 9 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
+4
fs/hfsplus/dir.c
··· 16 16 #include "hfsplus_fs.h" 17 17 #include "hfsplus_raw.h" 18 18 #include "xattr.h" 19 + #include "acl.h" 19 20 20 21 static inline void hfsplus_instantiate(struct dentry *dentry, 21 22 struct inode *inode, u32 cnid) ··· 530 529 .getxattr = generic_getxattr, 531 530 .listxattr = hfsplus_listxattr, 532 531 .removexattr = hfsplus_removexattr, 532 + #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 533 + .get_acl = hfsplus_get_posix_acl, 534 + #endif 533 535 }; 534 536 535 537 const struct file_operations hfsplus_dir_operations = {
+11
fs/hfsplus/inode.c
··· 19 19 #include "hfsplus_fs.h" 20 20 #include "hfsplus_raw.h" 21 21 #include "xattr.h" 22 + #include "acl.h" 22 23 23 24 static int hfsplus_readpage(struct file *file, struct page *page) 24 25 { ··· 317 316 318 317 setattr_copy(inode, attr); 319 318 mark_inode_dirty(inode); 319 + 320 + if (attr->ia_valid & ATTR_MODE) { 321 + error = hfsplus_posix_acl_chmod(inode); 322 + if (unlikely(error)) 323 + return error; 324 + } 325 + 320 326 return 0; 321 327 } 322 328 ··· 391 383 .getxattr = generic_getxattr, 392 384 .listxattr = hfsplus_listxattr, 393 385 .removexattr = hfsplus_removexattr, 386 + #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 387 + .get_acl = hfsplus_get_posix_acl, 388 + #endif 394 389 }; 395 390 396 391 static const struct file_operations hfsplus_file_operations = {
+56 -6
fs/hfsplus/xattr.c
··· 8 8 9 9 #include "hfsplus_fs.h" 10 10 #include "xattr.h" 11 + #include "acl.h" 11 12 12 13 const struct xattr_handler *hfsplus_xattr_handlers[] = { 13 14 &hfsplus_xattr_osx_handler, 14 15 &hfsplus_xattr_user_handler, 15 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 21 &hfsplus_xattr_security_handler, 17 22 NULL 18 23 }; ··· 51 46 return true; 52 47 } 53 48 49 + static int can_set_system_xattr(struct inode *inode, const char *name, 50 + const void *value, size_t size) 51 + { 52 + #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 53 + struct posix_acl *acl; 54 + int err; 55 + 56 + if (!inode_owner_or_capable(inode)) 57 + return -EPERM; 58 + 59 + /* 60 + * POSIX_ACL_XATTR_ACCESS is tied to i_mode 61 + */ 62 + if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) { 63 + acl = posix_acl_from_xattr(&init_user_ns, value, size); 64 + if (IS_ERR(acl)) 65 + return PTR_ERR(acl); 66 + if (acl) { 67 + err = posix_acl_equiv_mode(acl, &inode->i_mode); 68 + posix_acl_release(acl); 69 + if (err < 0) 70 + return err; 71 + mark_inode_dirty(inode); 72 + } 73 + /* 74 + * We're changing the ACL. Get rid of the cached one 75 + */ 76 + forget_cached_acl(inode, ACL_TYPE_ACCESS); 77 + 78 + return 0; 79 + } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { 80 + acl = posix_acl_from_xattr(&init_user_ns, value, size); 81 + if (IS_ERR(acl)) 82 + return PTR_ERR(acl); 83 + posix_acl_release(acl); 84 + 85 + /* 86 + * We're changing the default ACL. Get rid of the cached one 87 + */ 88 + forget_cached_acl(inode, ACL_TYPE_DEFAULT); 89 + 90 + return 0; 91 + } 92 + #endif /* CONFIG_HFSPLUS_FS_POSIX_ACL */ 93 + return -EOPNOTSUPP; 94 + } 95 + 54 96 static int can_set_xattr(struct inode *inode, const char *name, 55 97 const void *value, size_t value_len) 56 98 { 57 99 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 58 - return -EOPNOTSUPP; /* TODO: implement ACL support */ 100 + return can_set_system_xattr(inode, name, value, value_len); 59 101 60 102 if (!strncmp(name, XATTR_MAC_OSX_PREFIX, XATTR_MAC_OSX_PREFIX_LEN)) { 61 103 /* ··· 305 253 return len; 306 254 } 307 255 308 - static ssize_t hfsplus_getxattr_finder_info(struct dentry *dentry, 256 + static ssize_t hfsplus_getxattr_finder_info(struct inode *inode, 309 257 void *value, size_t size) 310 258 { 311 259 ssize_t res = 0; 312 - struct inode *inode = dentry->d_inode; 313 260 struct hfs_find_data fd; 314 261 u16 entry_type; 315 262 u16 folder_rec_len = sizeof(struct DInfo) + sizeof(struct DXInfo); ··· 355 304 return res; 356 305 } 357 306 358 - ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, 307 + ssize_t __hfsplus_getxattr(struct inode *inode, const char *name, 359 308 void *value, size_t size) 360 309 { 361 - struct inode *inode = dentry->d_inode; 362 310 struct hfs_find_data fd; 363 311 hfsplus_attr_entry *entry; 364 312 __be32 xattr_record_type; ··· 383 333 } 384 334 385 335 if (!strcmp_xattr_finder_info(name)) 386 - return hfsplus_getxattr_finder_info(dentry, value, size); 336 + return hfsplus_getxattr_finder_info(inode, value, size); 387 337 388 338 if (!HFSPLUS_SB(inode->i_sb)->attr_tree) 389 339 return -EOPNOTSUPP;
+13 -20
fs/hfsplus/xattr.h
··· 14 14 extern const struct xattr_handler hfsplus_xattr_osx_handler; 15 15 extern const struct xattr_handler hfsplus_xattr_user_handler; 16 16 extern const struct xattr_handler hfsplus_xattr_trusted_handler; 17 - /*extern const struct xattr_handler hfsplus_xattr_acl_access_handler;*/ 18 - /*extern const struct xattr_handler hfsplus_xattr_acl_default_handler;*/ 17 + extern const struct xattr_handler hfsplus_xattr_acl_access_handler; 18 + extern const struct xattr_handler hfsplus_xattr_acl_default_handler; 19 19 extern const struct xattr_handler hfsplus_xattr_security_handler; 20 20 21 21 extern const struct xattr_handler *hfsplus_xattr_handlers[]; ··· 29 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 33 void *value, size_t size); 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 + } 34 42 35 43 ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size); 36 44 ··· 47 39 int hfsplus_init_security(struct inode *inode, struct inode *dir, 48 40 const struct qstr *qstr); 49 41 50 - static inline int hfsplus_init_acl(struct inode *inode, struct inode *dir) 51 - { 52 - /*TODO: implement*/ 53 - return 0; 54 - } 55 - 56 - static inline int hfsplus_init_inode_security(struct inode *inode, 57 - struct inode *dir, 58 - const struct qstr *qstr) 59 - { 60 - int err; 61 - 62 - err = hfsplus_init_acl(inode, dir); 63 - if (!err) 64 - err = hfsplus_init_security(inode, dir, qstr); 65 - return err; 66 - } 42 + int hfsplus_init_inode_security(struct inode *inode, struct inode *dir, 43 + const struct qstr *qstr); 67 44 68 45 #endif
+13
fs/hfsplus/xattr_security.c
··· 9 9 #include <linux/security.h> 10 10 #include "hfsplus_fs.h" 11 11 #include "xattr.h" 12 + #include "acl.h" 12 13 13 14 static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, 14 15 void *buffer, size_t size, int type) ··· 95 94 { 96 95 return security_inode_init_security(inode, dir, qstr, 97 96 &hfsplus_initxattrs, NULL); 97 + } 98 + 99 + int hfsplus_init_inode_security(struct inode *inode, 100 + struct inode *dir, 101 + const struct qstr *qstr) 102 + { 103 + int err; 104 + 105 + err = hfsplus_init_posix_acl(inode, dir); 106 + if (!err) 107 + err = hfsplus_init_security(inode, dir, qstr); 108 + return err; 98 109 } 99 110 100 111 const struct xattr_handler hfsplus_xattr_security_handler = {