diff options
Diffstat (limited to 'fs/reiserfs/ioctl.c')
-rw-r--r-- | fs/reiserfs/ioctl.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 5e40b0cd4c3d..e30e8be09179 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -13,44 +13,52 @@ | |||
13 | #include <linux/compat.h> | 13 | #include <linux/compat.h> |
14 | 14 | ||
15 | /* | 15 | /* |
16 | ** reiserfs_ioctl - handler for ioctl for inode | 16 | * reiserfs_ioctl - handler for ioctl for inode |
17 | ** supported commands: | 17 | * supported commands: |
18 | ** 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect | 18 | * 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect |
19 | ** and prevent packing file (argument arg has to be non-zero) | 19 | * and prevent packing file (argument arg has to be non-zero) |
20 | ** 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION | 20 | * 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION |
21 | ** 3) That's all for a while ... | 21 | * 3) That's all for a while ... |
22 | */ | 22 | */ |
23 | int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 23 | int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, |
24 | unsigned long arg) | 24 | unsigned long arg) |
25 | { | 25 | { |
26 | unsigned int flags; | 26 | unsigned int flags; |
27 | int err = 0; | 27 | int err = 0; |
28 | 28 | ||
29 | reiserfs_write_lock(inode->i_sb); | ||
30 | |||
29 | switch (cmd) { | 31 | switch (cmd) { |
30 | case REISERFS_IOC_UNPACK: | 32 | case REISERFS_IOC_UNPACK: |
31 | if (S_ISREG(inode->i_mode)) { | 33 | if (S_ISREG(inode->i_mode)) { |
32 | if (arg) | 34 | if (arg) |
33 | return reiserfs_unpack(inode, filp); | 35 | err = reiserfs_unpack(inode, filp); |
34 | else | ||
35 | return 0; | ||
36 | } else | 36 | } else |
37 | return -ENOTTY; | 37 | err = -ENOTTY; |
38 | /* following two cases are taken from fs/ext2/ioctl.c by Remy | 38 | break; |
39 | Card (card@masi.ibp.fr) */ | 39 | /* |
40 | * following two cases are taken from fs/ext2/ioctl.c by Remy | ||
41 | * Card (card@masi.ibp.fr) | ||
42 | */ | ||
40 | case REISERFS_IOC_GETFLAGS: | 43 | case REISERFS_IOC_GETFLAGS: |
41 | if (!reiserfs_attrs(inode->i_sb)) | 44 | if (!reiserfs_attrs(inode->i_sb)) { |
42 | return -ENOTTY; | 45 | err = -ENOTTY; |
46 | break; | ||
47 | } | ||
43 | 48 | ||
44 | flags = REISERFS_I(inode)->i_attrs; | 49 | flags = REISERFS_I(inode)->i_attrs; |
45 | i_attrs_to_sd_attrs(inode, (__u16 *) & flags); | 50 | i_attrs_to_sd_attrs(inode, (__u16 *) & flags); |
46 | return put_user(flags, (int __user *)arg); | 51 | err = put_user(flags, (int __user *)arg); |
52 | break; | ||
47 | case REISERFS_IOC_SETFLAGS:{ | 53 | case REISERFS_IOC_SETFLAGS:{ |
48 | if (!reiserfs_attrs(inode->i_sb)) | 54 | if (!reiserfs_attrs(inode->i_sb)) { |
49 | return -ENOTTY; | 55 | err = -ENOTTY; |
56 | break; | ||
57 | } | ||
50 | 58 | ||
51 | err = mnt_want_write(filp->f_path.mnt); | 59 | err = mnt_want_write(filp->f_path.mnt); |
52 | if (err) | 60 | if (err) |
53 | return err; | 61 | break; |
54 | 62 | ||
55 | if (!is_owner_or_cap(inode)) { | 63 | if (!is_owner_or_cap(inode)) { |
56 | err = -EPERM; | 64 | err = -EPERM; |
@@ -90,16 +98,18 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
90 | mark_inode_dirty(inode); | 98 | mark_inode_dirty(inode); |
91 | setflags_out: | 99 | setflags_out: |
92 | mnt_drop_write(filp->f_path.mnt); | 100 | mnt_drop_write(filp->f_path.mnt); |
93 | return err; | 101 | break; |
94 | } | 102 | } |
95 | case REISERFS_IOC_GETVERSION: | 103 | case REISERFS_IOC_GETVERSION: |
96 | return put_user(inode->i_generation, (int __user *)arg); | 104 | err = put_user(inode->i_generation, (int __user *)arg); |
105 | break; | ||
97 | case REISERFS_IOC_SETVERSION: | 106 | case REISERFS_IOC_SETVERSION: |
98 | if (!is_owner_or_cap(inode)) | 107 | if (!is_owner_or_cap(inode)) |
99 | return -EPERM; | 108 | err = -EPERM; |
109 | break; | ||
100 | err = mnt_want_write(filp->f_path.mnt); | 110 | err = mnt_want_write(filp->f_path.mnt); |
101 | if (err) | 111 | if (err) |
102 | return err; | 112 | break; |
103 | if (get_user(inode->i_generation, (int __user *)arg)) { | 113 | if (get_user(inode->i_generation, (int __user *)arg)) { |
104 | err = -EFAULT; | 114 | err = -EFAULT; |
105 | goto setversion_out; | 115 | goto setversion_out; |
@@ -108,10 +118,14 @@ setflags_out: | |||
108 | mark_inode_dirty(inode); | 118 | mark_inode_dirty(inode); |
109 | setversion_out: | 119 | setversion_out: |
110 | mnt_drop_write(filp->f_path.mnt); | 120 | mnt_drop_write(filp->f_path.mnt); |
111 | return err; | 121 | break; |
112 | default: | 122 | default: |
113 | return -ENOTTY; | 123 | err = -ENOTTY; |
114 | } | 124 | } |
125 | |||
126 | reiserfs_write_unlock(inode->i_sb); | ||
127 | |||
128 | return err; | ||
115 | } | 129 | } |
116 | 130 | ||
117 | #ifdef CONFIG_COMPAT | 131 | #ifdef CONFIG_COMPAT |
@@ -142,9 +156,7 @@ long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, | |||
142 | return -ENOIOCTLCMD; | 156 | return -ENOIOCTLCMD; |
143 | } | 157 | } |
144 | 158 | ||
145 | reiserfs_write_lock(inode->i_sb); | ||
146 | ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | 159 | ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); |
147 | reiserfs_write_unlock(inode->i_sb); | ||
148 | 160 | ||
149 | return ret; | 161 | return ret; |
150 | } | 162 | } |