diff options
| -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 | } |
