diff options
author | Christoph Hellwig <hch@lst.de> | 2010-09-30 23:41:31 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2010-09-30 23:41:31 -0400 |
commit | 94744567fef9602c3d8218a1d8f58c04cce354f6 (patch) | |
tree | 9bbe93c54ea8e1201fa0d59a10e17bba03d09b53 /fs | |
parent | 249e6353001e407edf5c9a74482ecfca90c8ff33 (diff) |
hfsplus: split hfsplus_ioctl
Give each ioctl command a function of it's own.
Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/hfsplus/ioctl.c | 145 |
1 files changed, 80 insertions, 65 deletions
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index 59dc402dfe95..0e359c3b55ee 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c | |||
@@ -21,78 +21,93 @@ | |||
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | #include "hfsplus_fs.h" | 22 | #include "hfsplus_fs.h" |
23 | 23 | ||
24 | long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 24 | static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) |
25 | { | 25 | { |
26 | struct inode *inode = filp->f_path.dentry->d_inode; | 26 | struct inode *inode = file->f_path.dentry->d_inode; |
27 | unsigned int flags = 0; | ||
28 | |||
29 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_IMMUTABLE) | ||
30 | flags |= FS_IMMUTABLE_FL; | ||
31 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_APPEND) | ||
32 | flags |= FS_APPEND_FL; | ||
33 | if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP) | ||
34 | flags |= FS_NODUMP_FL; | ||
35 | |||
36 | return put_user(flags, user_flags); | ||
37 | } | ||
38 | |||
39 | static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) | ||
40 | { | ||
41 | struct inode *inode = file->f_path.dentry->d_inode; | ||
27 | unsigned int flags; | 42 | unsigned int flags; |
43 | int err = 0; | ||
28 | 44 | ||
29 | switch (cmd) { | 45 | lock_kernel(); |
30 | case HFSPLUS_IOC_EXT2_GETFLAGS: | 46 | err = mnt_want_write(file->f_path.mnt); |
31 | flags = 0; | 47 | if (err) |
32 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_IMMUTABLE) | 48 | goto out_unlock_kernel; |
33 | flags |= FS_IMMUTABLE_FL; /* EXT2_IMMUTABLE_FL */ | ||
34 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_APPEND) | ||
35 | flags |= FS_APPEND_FL; /* EXT2_APPEND_FL */ | ||
36 | if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP) | ||
37 | flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */ | ||
38 | return put_user(flags, (int __user *)arg); | ||
39 | case HFSPLUS_IOC_EXT2_SETFLAGS: { | ||
40 | int err = 0; | ||
41 | |||
42 | lock_kernel(); | ||
43 | err = mnt_want_write(filp->f_path.mnt); | ||
44 | if (err) { | ||
45 | unlock_kernel(); | ||
46 | return err; | ||
47 | } | ||
48 | 49 | ||
49 | if (!is_owner_or_cap(inode)) { | 50 | if (!is_owner_or_cap(inode)) { |
50 | err = -EACCES; | 51 | err = -EACCES; |
51 | goto setflags_out; | 52 | goto out_drop_write; |
52 | } | 53 | } |
53 | if (get_user(flags, (int __user *)arg)) { | ||
54 | err = -EFAULT; | ||
55 | goto setflags_out; | ||
56 | } | ||
57 | if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || | ||
58 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { | ||
59 | if (!capable(CAP_LINUX_IMMUTABLE)) { | ||
60 | err = -EPERM; | ||
61 | goto setflags_out; | ||
62 | } | ||
63 | } | ||
64 | 54 | ||
65 | /* don't silently ignore unsupported ext2 flags */ | 55 | if (get_user(flags, user_flags)) { |
66 | if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { | 56 | err = -EFAULT; |
67 | err = -EOPNOTSUPP; | 57 | goto out_drop_write; |
68 | goto setflags_out; | 58 | } |
69 | } | 59 | |
70 | if (flags & FS_IMMUTABLE_FL) { /* EXT2_IMMUTABLE_FL */ | 60 | if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || |
71 | inode->i_flags |= S_IMMUTABLE; | 61 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { |
72 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; | 62 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
73 | } else { | 63 | err = -EPERM; |
74 | inode->i_flags &= ~S_IMMUTABLE; | 64 | goto out_drop_write; |
75 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_IMMUTABLE; | ||
76 | } | ||
77 | if (flags & FS_APPEND_FL) { /* EXT2_APPEND_FL */ | ||
78 | inode->i_flags |= S_APPEND; | ||
79 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_APPEND; | ||
80 | } else { | ||
81 | inode->i_flags &= ~S_APPEND; | ||
82 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND; | ||
83 | } | 65 | } |
84 | if (flags & FS_NODUMP_FL) /* EXT2_NODUMP_FL */ | ||
85 | HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP; | ||
86 | else | ||
87 | HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP; | ||
88 | |||
89 | inode->i_ctime = CURRENT_TIME_SEC; | ||
90 | mark_inode_dirty(inode); | ||
91 | setflags_out: | ||
92 | mnt_drop_write(filp->f_path.mnt); | ||
93 | unlock_kernel(); | ||
94 | return err; | ||
95 | } | 66 | } |
67 | |||
68 | /* don't silently ignore unsupported ext2 flags */ | ||
69 | if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { | ||
70 | err = -EOPNOTSUPP; | ||
71 | goto out_drop_write; | ||
72 | } | ||
73 | if (flags & FS_IMMUTABLE_FL) { | ||
74 | inode->i_flags |= S_IMMUTABLE; | ||
75 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; | ||
76 | } else { | ||
77 | inode->i_flags &= ~S_IMMUTABLE; | ||
78 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_IMMUTABLE; | ||
79 | } | ||
80 | if (flags & FS_APPEND_FL) { | ||
81 | inode->i_flags |= S_APPEND; | ||
82 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_APPEND; | ||
83 | } else { | ||
84 | inode->i_flags &= ~S_APPEND; | ||
85 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND; | ||
86 | } | ||
87 | if (flags & FS_NODUMP_FL) | ||
88 | HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP; | ||
89 | else | ||
90 | HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP; | ||
91 | |||
92 | inode->i_ctime = CURRENT_TIME_SEC; | ||
93 | mark_inode_dirty(inode); | ||
94 | |||
95 | out_drop_write: | ||
96 | mnt_drop_write(file->f_path.mnt); | ||
97 | out_unlock_kernel: | ||
98 | unlock_kernel(); | ||
99 | return err; | ||
100 | } | ||
101 | |||
102 | long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
103 | { | ||
104 | void __user *argp = (void __user *)arg; | ||
105 | |||
106 | switch (cmd) { | ||
107 | case HFSPLUS_IOC_EXT2_GETFLAGS: | ||
108 | return hfsplus_ioctl_getflags(file, argp); | ||
109 | case HFSPLUS_IOC_EXT2_SETFLAGS: | ||
110 | return hfsplus_ioctl_setflags(file, argp); | ||
96 | default: | 111 | default: |
97 | return -ENOTTY; | 112 | return -ENOTTY; |
98 | } | 113 | } |