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

hfsplus: convert to fileattr

Use the fileattr API to let the VFS handle locking, permission checking and
conversion.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

+59 -95
+2
fs/hfsplus/dir.c
··· 569 569 .rename = hfsplus_rename, 570 570 .getattr = hfsplus_getattr, 571 571 .listxattr = hfsplus_listxattr, 572 + .fileattr_get = hfsplus_fileattr_get, 573 + .fileattr_set = hfsplus_fileattr_set, 572 574 }; 573 575 574 576 const struct file_operations hfsplus_dir_operations = {
+3 -11
fs/hfsplus/hfsplus_fs.h
··· 345 345 #define hfs_part_find hfsplus_part_find 346 346 347 347 /* 348 - * definitions for ext2 flag ioctls (linux really needs a generic 349 - * interface for this). 350 - */ 351 - 352 - /* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support 353 - * chattr/lsattr */ 354 - #define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS 355 - #define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS 356 - 357 - 358 - /* 359 348 * hfs+-specific ioctl for making the filesystem bootable 360 349 */ 361 350 #define HFSPLUS_IOC_BLESS _IO('h', 0x80) ··· 482 493 unsigned int query_flags); 483 494 int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, 484 495 int datasync); 496 + int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa); 497 + int hfsplus_fileattr_set(struct user_namespace *mnt_userns, 498 + struct dentry *dentry, struct fileattr *fa); 485 499 486 500 /* ioctl.c */ 487 501 long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+54
fs/hfsplus/inode.c
··· 17 17 #include <linux/sched.h> 18 18 #include <linux/cred.h> 19 19 #include <linux/uio.h> 20 + #include <linux/fileattr.h> 20 21 21 22 #include "hfsplus_fs.h" 22 23 #include "hfsplus_raw.h" ··· 354 353 .setattr = hfsplus_setattr, 355 354 .getattr = hfsplus_getattr, 356 355 .listxattr = hfsplus_listxattr, 356 + .fileattr_get = hfsplus_fileattr_get, 357 + .fileattr_set = hfsplus_fileattr_set, 357 358 }; 358 359 359 360 static const struct file_operations hfsplus_file_operations = { ··· 629 626 set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); 630 627 out: 631 628 hfs_find_exit(&fd); 629 + return 0; 630 + } 631 + 632 + int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa) 633 + { 634 + struct inode *inode = d_inode(dentry); 635 + struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 636 + unsigned int flags = 0; 637 + 638 + if (inode->i_flags & S_IMMUTABLE) 639 + flags |= FS_IMMUTABLE_FL; 640 + if (inode->i_flags & S_APPEND) 641 + flags |= FS_APPEND_FL; 642 + if (hip->userflags & HFSPLUS_FLG_NODUMP) 643 + flags |= FS_NODUMP_FL; 644 + 645 + fileattr_fill_flags(fa, flags); 646 + 647 + return 0; 648 + } 649 + 650 + int hfsplus_fileattr_set(struct user_namespace *mnt_userns, 651 + struct dentry *dentry, struct fileattr *fa) 652 + { 653 + struct inode *inode = d_inode(dentry); 654 + struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 655 + unsigned int new_fl = 0; 656 + 657 + if (fileattr_has_fsx(fa)) 658 + return -EOPNOTSUPP; 659 + 660 + /* don't silently ignore unsupported ext2 flags */ 661 + if (fa->flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) 662 + return -EOPNOTSUPP; 663 + 664 + if (fa->flags & FS_IMMUTABLE_FL) 665 + new_fl |= S_IMMUTABLE; 666 + 667 + if (fa->flags & FS_APPEND_FL) 668 + new_fl |= S_APPEND; 669 + 670 + inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); 671 + 672 + if (fa->flags & FS_NODUMP_FL) 673 + hip->userflags |= HFSPLUS_FLG_NODUMP; 674 + else 675 + hip->userflags &= ~HFSPLUS_FLG_NODUMP; 676 + 677 + inode->i_ctime = current_time(inode); 678 + mark_inode_dirty(inode); 679 + 632 680 return 0; 633 681 }
-84
fs/hfsplus/ioctl.c
··· 57 57 return 0; 58 58 } 59 59 60 - static inline unsigned int hfsplus_getflags(struct inode *inode) 61 - { 62 - struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 63 - unsigned int flags = 0; 64 - 65 - if (inode->i_flags & S_IMMUTABLE) 66 - flags |= FS_IMMUTABLE_FL; 67 - if (inode->i_flags & S_APPEND) 68 - flags |= FS_APPEND_FL; 69 - if (hip->userflags & HFSPLUS_FLG_NODUMP) 70 - flags |= FS_NODUMP_FL; 71 - return flags; 72 - } 73 - 74 - static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) 75 - { 76 - struct inode *inode = file_inode(file); 77 - unsigned int flags = hfsplus_getflags(inode); 78 - 79 - return put_user(flags, user_flags); 80 - } 81 - 82 - static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) 83 - { 84 - struct inode *inode = file_inode(file); 85 - struct hfsplus_inode_info *hip = HFSPLUS_I(inode); 86 - unsigned int flags, new_fl = 0; 87 - unsigned int oldflags = hfsplus_getflags(inode); 88 - int err = 0; 89 - 90 - err = mnt_want_write_file(file); 91 - if (err) 92 - goto out; 93 - 94 - if (!inode_owner_or_capable(&init_user_ns, inode)) { 95 - err = -EACCES; 96 - goto out_drop_write; 97 - } 98 - 99 - if (get_user(flags, user_flags)) { 100 - err = -EFAULT; 101 - goto out_drop_write; 102 - } 103 - 104 - inode_lock(inode); 105 - 106 - err = vfs_ioc_setflags_prepare(inode, oldflags, flags); 107 - if (err) 108 - goto out_unlock_inode; 109 - 110 - /* don't silently ignore unsupported ext2 flags */ 111 - if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { 112 - err = -EOPNOTSUPP; 113 - goto out_unlock_inode; 114 - } 115 - 116 - if (flags & FS_IMMUTABLE_FL) 117 - new_fl |= S_IMMUTABLE; 118 - 119 - if (flags & FS_APPEND_FL) 120 - new_fl |= S_APPEND; 121 - 122 - inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); 123 - 124 - if (flags & FS_NODUMP_FL) 125 - hip->userflags |= HFSPLUS_FLG_NODUMP; 126 - else 127 - hip->userflags &= ~HFSPLUS_FLG_NODUMP; 128 - 129 - inode->i_ctime = current_time(inode); 130 - mark_inode_dirty(inode); 131 - 132 - out_unlock_inode: 133 - inode_unlock(inode); 134 - out_drop_write: 135 - mnt_drop_write_file(file); 136 - out: 137 - return err; 138 - } 139 - 140 60 long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 141 61 { 142 62 void __user *argp = (void __user *)arg; 143 63 144 64 switch (cmd) { 145 - case HFSPLUS_IOC_EXT2_GETFLAGS: 146 - return hfsplus_ioctl_getflags(file, argp); 147 - case HFSPLUS_IOC_EXT2_SETFLAGS: 148 - return hfsplus_ioctl_setflags(file, argp); 149 65 case HFSPLUS_IOC_BLESS: 150 66 return hfsplus_ioctl_bless(file, argp); 151 67 default: