Loading fs/hfsplus/dir.c +2 −0 Original line number Diff line number Diff line Loading @@ -569,6 +569,8 @@ const struct inode_operations hfsplus_dir_inode_operations = { .rename = hfsplus_rename, .getattr = hfsplus_getattr, .listxattr = hfsplus_listxattr, .fileattr_get = hfsplus_fileattr_get, .fileattr_set = hfsplus_fileattr_set, }; const struct file_operations hfsplus_dir_operations = { Loading fs/hfsplus/hfsplus_fs.h +3 −11 Original line number Diff line number Diff line Loading @@ -344,17 +344,6 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb) #define hfs_brec_goto hfsplus_brec_goto #define hfs_part_find hfsplus_part_find /* * definitions for ext2 flag ioctls (linux really needs a generic * interface for this). */ /* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support * chattr/lsattr */ #define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS #define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS /* * hfs+-specific ioctl for making the filesystem bootable */ Loading Loading @@ -493,6 +482,9 @@ int hfsplus_getattr(struct user_namespace *mnt_userns, const struct path *path, unsigned int query_flags); int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa); int hfsplus_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, struct fileattr *fa); /* ioctl.c */ long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); Loading fs/hfsplus/inode.c +54 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/sched.h> #include <linux/cred.h> #include <linux/uio.h> #include <linux/fileattr.h> #include "hfsplus_fs.h" #include "hfsplus_raw.h" Loading Loading @@ -353,6 +354,8 @@ static const struct inode_operations hfsplus_file_inode_operations = { .setattr = hfsplus_setattr, .getattr = hfsplus_getattr, .listxattr = hfsplus_listxattr, .fileattr_get = hfsplus_fileattr_get, .fileattr_set = hfsplus_fileattr_set, }; static const struct file_operations hfsplus_file_operations = { Loading Loading @@ -628,3 +631,54 @@ int hfsplus_cat_write_inode(struct inode *inode) hfs_find_exit(&fd); return 0; } int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa) { struct inode *inode = d_inode(dentry); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int flags = 0; if (inode->i_flags & S_IMMUTABLE) flags |= FS_IMMUTABLE_FL; if (inode->i_flags & S_APPEND) flags |= FS_APPEND_FL; if (hip->userflags & HFSPLUS_FLG_NODUMP) flags |= FS_NODUMP_FL; fileattr_fill_flags(fa, flags); return 0; } int hfsplus_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, struct fileattr *fa) { struct inode *inode = d_inode(dentry); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int new_fl = 0; if (fileattr_has_fsx(fa)) return -EOPNOTSUPP; /* don't silently ignore unsupported ext2 flags */ if (fa->flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) return -EOPNOTSUPP; if (fa->flags & FS_IMMUTABLE_FL) new_fl |= S_IMMUTABLE; if (fa->flags & FS_APPEND_FL) new_fl |= S_APPEND; inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); if (fa->flags & FS_NODUMP_FL) hip->userflags |= HFSPLUS_FLG_NODUMP; else hip->userflags &= ~HFSPLUS_FLG_NODUMP; inode->i_ctime = current_time(inode); mark_inode_dirty(inode); return 0; } fs/hfsplus/ioctl.c +0 −84 Original line number Diff line number Diff line Loading @@ -57,95 +57,11 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) return 0; } static inline unsigned int hfsplus_getflags(struct inode *inode) { struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int flags = 0; if (inode->i_flags & S_IMMUTABLE) flags |= FS_IMMUTABLE_FL; if (inode->i_flags & S_APPEND) flags |= FS_APPEND_FL; if (hip->userflags & HFSPLUS_FLG_NODUMP) flags |= FS_NODUMP_FL; return flags; } static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) { struct inode *inode = file_inode(file); unsigned int flags = hfsplus_getflags(inode); return put_user(flags, user_flags); } static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) { struct inode *inode = file_inode(file); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int flags, new_fl = 0; unsigned int oldflags = hfsplus_getflags(inode); int err = 0; err = mnt_want_write_file(file); if (err) goto out; if (!inode_owner_or_capable(&init_user_ns, inode)) { err = -EACCES; goto out_drop_write; } if (get_user(flags, user_flags)) { err = -EFAULT; goto out_drop_write; } inode_lock(inode); err = vfs_ioc_setflags_prepare(inode, oldflags, flags); if (err) goto out_unlock_inode; /* don't silently ignore unsupported ext2 flags */ if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { err = -EOPNOTSUPP; goto out_unlock_inode; } if (flags & FS_IMMUTABLE_FL) new_fl |= S_IMMUTABLE; if (flags & FS_APPEND_FL) new_fl |= S_APPEND; inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); if (flags & FS_NODUMP_FL) hip->userflags |= HFSPLUS_FLG_NODUMP; else hip->userflags &= ~HFSPLUS_FLG_NODUMP; inode->i_ctime = current_time(inode); mark_inode_dirty(inode); out_unlock_inode: inode_unlock(inode); out_drop_write: mnt_drop_write_file(file); out: return err; } long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; switch (cmd) { case HFSPLUS_IOC_EXT2_GETFLAGS: return hfsplus_ioctl_getflags(file, argp); case HFSPLUS_IOC_EXT2_SETFLAGS: return hfsplus_ioctl_setflags(file, argp); case HFSPLUS_IOC_BLESS: return hfsplus_ioctl_bless(file, argp); default: Loading Loading
fs/hfsplus/dir.c +2 −0 Original line number Diff line number Diff line Loading @@ -569,6 +569,8 @@ const struct inode_operations hfsplus_dir_inode_operations = { .rename = hfsplus_rename, .getattr = hfsplus_getattr, .listxattr = hfsplus_listxattr, .fileattr_get = hfsplus_fileattr_get, .fileattr_set = hfsplus_fileattr_set, }; const struct file_operations hfsplus_dir_operations = { Loading
fs/hfsplus/hfsplus_fs.h +3 −11 Original line number Diff line number Diff line Loading @@ -344,17 +344,6 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb) #define hfs_brec_goto hfsplus_brec_goto #define hfs_part_find hfsplus_part_find /* * definitions for ext2 flag ioctls (linux really needs a generic * interface for this). */ /* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support * chattr/lsattr */ #define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS #define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS /* * hfs+-specific ioctl for making the filesystem bootable */ Loading Loading @@ -493,6 +482,9 @@ int hfsplus_getattr(struct user_namespace *mnt_userns, const struct path *path, unsigned int query_flags); int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa); int hfsplus_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, struct fileattr *fa); /* ioctl.c */ long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); Loading
fs/hfsplus/inode.c +54 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/sched.h> #include <linux/cred.h> #include <linux/uio.h> #include <linux/fileattr.h> #include "hfsplus_fs.h" #include "hfsplus_raw.h" Loading Loading @@ -353,6 +354,8 @@ static const struct inode_operations hfsplus_file_inode_operations = { .setattr = hfsplus_setattr, .getattr = hfsplus_getattr, .listxattr = hfsplus_listxattr, .fileattr_get = hfsplus_fileattr_get, .fileattr_set = hfsplus_fileattr_set, }; static const struct file_operations hfsplus_file_operations = { Loading Loading @@ -628,3 +631,54 @@ int hfsplus_cat_write_inode(struct inode *inode) hfs_find_exit(&fd); return 0; } int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa) { struct inode *inode = d_inode(dentry); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int flags = 0; if (inode->i_flags & S_IMMUTABLE) flags |= FS_IMMUTABLE_FL; if (inode->i_flags & S_APPEND) flags |= FS_APPEND_FL; if (hip->userflags & HFSPLUS_FLG_NODUMP) flags |= FS_NODUMP_FL; fileattr_fill_flags(fa, flags); return 0; } int hfsplus_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, struct fileattr *fa) { struct inode *inode = d_inode(dentry); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int new_fl = 0; if (fileattr_has_fsx(fa)) return -EOPNOTSUPP; /* don't silently ignore unsupported ext2 flags */ if (fa->flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) return -EOPNOTSUPP; if (fa->flags & FS_IMMUTABLE_FL) new_fl |= S_IMMUTABLE; if (fa->flags & FS_APPEND_FL) new_fl |= S_APPEND; inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); if (fa->flags & FS_NODUMP_FL) hip->userflags |= HFSPLUS_FLG_NODUMP; else hip->userflags &= ~HFSPLUS_FLG_NODUMP; inode->i_ctime = current_time(inode); mark_inode_dirty(inode); return 0; }
fs/hfsplus/ioctl.c +0 −84 Original line number Diff line number Diff line Loading @@ -57,95 +57,11 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) return 0; } static inline unsigned int hfsplus_getflags(struct inode *inode) { struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int flags = 0; if (inode->i_flags & S_IMMUTABLE) flags |= FS_IMMUTABLE_FL; if (inode->i_flags & S_APPEND) flags |= FS_APPEND_FL; if (hip->userflags & HFSPLUS_FLG_NODUMP) flags |= FS_NODUMP_FL; return flags; } static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) { struct inode *inode = file_inode(file); unsigned int flags = hfsplus_getflags(inode); return put_user(flags, user_flags); } static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) { struct inode *inode = file_inode(file); struct hfsplus_inode_info *hip = HFSPLUS_I(inode); unsigned int flags, new_fl = 0; unsigned int oldflags = hfsplus_getflags(inode); int err = 0; err = mnt_want_write_file(file); if (err) goto out; if (!inode_owner_or_capable(&init_user_ns, inode)) { err = -EACCES; goto out_drop_write; } if (get_user(flags, user_flags)) { err = -EFAULT; goto out_drop_write; } inode_lock(inode); err = vfs_ioc_setflags_prepare(inode, oldflags, flags); if (err) goto out_unlock_inode; /* don't silently ignore unsupported ext2 flags */ if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { err = -EOPNOTSUPP; goto out_unlock_inode; } if (flags & FS_IMMUTABLE_FL) new_fl |= S_IMMUTABLE; if (flags & FS_APPEND_FL) new_fl |= S_APPEND; inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); if (flags & FS_NODUMP_FL) hip->userflags |= HFSPLUS_FLG_NODUMP; else hip->userflags &= ~HFSPLUS_FLG_NODUMP; inode->i_ctime = current_time(inode); mark_inode_dirty(inode); out_unlock_inode: inode_unlock(inode); out_drop_write: mnt_drop_write_file(file); out: return err; } long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; switch (cmd) { case HFSPLUS_IOC_EXT2_GETFLAGS: return hfsplus_ioctl_getflags(file, argp); case HFSPLUS_IOC_EXT2_SETFLAGS: return hfsplus_ioctl_setflags(file, argp); case HFSPLUS_IOC_BLESS: return hfsplus_ioctl_bless(file, argp); default: Loading