Rebase to 2.6.24-git6. Remove patches which have been accepted by Linus.
[ext4-patch-queue.git] / ext2-unlocked-ioctl.patch
blob6d2010bed3f7d2e38f4d156d38c6e955f9e64ee5
1 Convert EXT2 to use unlocked_ioctl
3 From: Mathieu Segaud <mathieu.segaud@regala.cx>
5 Change ext2_ioctl() to be an unlocked_ioctl(), explicitly
6 exposing BKL's uses.
8 Signed-off-by: Mathieu Segaud <mathieu.segaud@regala.cx>
9 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
11 ---
12 fs/ext2/dir.c | 2 +-
13 fs/ext2/ext2.h | 3 +-
14 fs/ext2/file.c | 4 +-
15 fs/ext2/ioctl.c | 103 +++++++++++++++++++++++++++++++++++++------------------
16 4 files changed, 73 insertions(+), 39 deletions(-)
18 diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
19 index d868e26..dbee3c9 100644
20 --- a/fs/ext2/dir.c
21 +++ b/fs/ext2/dir.c
22 @@ -703,7 +703,7 @@ const struct file_operations ext2_dir_operations = {
23 .llseek = generic_file_llseek,
24 .read = generic_read_dir,
25 .readdir = ext2_readdir,
26 - .ioctl = ext2_ioctl,
27 + .unlocked_ioctl = ext2_ioctl,
28 #ifdef CONFIG_COMPAT
29 .compat_ioctl = ext2_compat_ioctl,
30 #endif
31 diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
32 index c87ae29..bb9948c 100644
33 --- a/fs/ext2/ext2.h
34 +++ b/fs/ext2/ext2.h
35 @@ -139,8 +139,7 @@ int __ext2_write_begin(struct file *file, struct address_space *mapping,
36 struct page **pagep, void **fsdata);
38 /* ioctl.c */
39 -extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
40 - unsigned long);
41 +extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
42 extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long);
44 /* namei.c */
45 diff --git a/fs/ext2/file.c b/fs/ext2/file.c
46 index c051798..17fe628 100644
47 --- a/fs/ext2/file.c
48 +++ b/fs/ext2/file.c
49 @@ -48,7 +48,7 @@ const struct file_operations ext2_file_operations = {
50 .write = do_sync_write,
51 .aio_read = generic_file_aio_read,
52 .aio_write = generic_file_aio_write,
53 - .ioctl = ext2_ioctl,
54 + .unlocked_ioctl = ext2_ioctl,
55 #ifdef CONFIG_COMPAT
56 .compat_ioctl = ext2_compat_ioctl,
57 #endif
58 @@ -65,7 +65,7 @@ const struct file_operations ext2_xip_file_operations = {
59 .llseek = generic_file_llseek,
60 .read = xip_file_read,
61 .write = xip_file_write,
62 - .ioctl = ext2_ioctl,
63 + .unlocked_ioctl = ext2_ioctl,
64 #ifdef CONFIG_COMPAT
65 .compat_ioctl = ext2_compat_ioctl,
66 #endif
67 diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
68 index 320b2cb..0f18ac5 100644
69 --- a/fs/ext2/ioctl.c
70 +++ b/fs/ext2/ioctl.c
71 @@ -17,12 +17,18 @@
72 #include <asm/uaccess.h>
75 -int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
76 +long ext2_ioctl(struct file *filp, unsigned int cmd,
77 unsigned long arg)
79 - struct ext2_inode_info *ei = EXT2_I(inode);
80 + struct ext2_inode_info *ei;
81 + struct inode *inode;
82 unsigned int flags;
83 unsigned short rsv_window_size;
84 + long retval = 0;
86 + lock_kernel();
87 + inode = filp->f_path.dentry->d_inode;
88 + ei = EXT2_I(inode);
90 ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);
92 @@ -30,18 +36,25 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
93 case EXT2_IOC_GETFLAGS:
94 ext2_get_inode_flags(ei);
95 flags = ei->i_flags & EXT2_FL_USER_VISIBLE;
96 - return put_user(flags, (int __user *) arg);
97 + retval = put_user(flags, (int __user *) arg);
98 + goto out;
99 case EXT2_IOC_SETFLAGS: {
100 unsigned int oldflags;
102 - if (IS_RDONLY(inode))
103 - return -EROFS;
104 + if (IS_RDONLY(inode)) {
105 + retval = -EROFS;
106 + goto out;
109 - if (!is_owner_or_cap(inode))
110 - return -EACCES;
111 + if (!is_owner_or_cap(inode)) {
112 + retval = -EACCES;
113 + goto out;
116 - if (get_user(flags, (int __user *) arg))
117 - return -EFAULT;
118 + if (get_user(flags, (int __user *) arg)) {
119 + retval = -EFAULT;
120 + goto out;
123 if (!S_ISDIR(inode->i_mode))
124 flags &= ~EXT2_DIRSYNC_FL;
125 @@ -50,7 +63,8 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
126 /* Is it quota file? Do not allow user to mess with it */
127 if (IS_NOQUOTA(inode)) {
128 mutex_unlock(&inode->i_mutex);
129 - return -EPERM;
130 + retval = -EPERM;
131 + goto out;
133 oldflags = ei->i_flags;
135 @@ -63,7 +77,8 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
136 if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
137 if (!capable(CAP_LINUX_IMMUTABLE)) {
138 mutex_unlock(&inode->i_mutex);
139 - return -EPERM;
140 + retval = -EPERM;
141 + goto out;
145 @@ -75,41 +90,59 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
146 ext2_set_inode_flags(inode);
147 inode->i_ctime = CURRENT_TIME_SEC;
148 mark_inode_dirty(inode);
149 - return 0;
150 + goto out;
152 case EXT2_IOC_GETVERSION:
153 - return put_user(inode->i_generation, (int __user *) arg);
154 + retval = put_user(inode->i_generation, (int __user *) arg);
155 + goto out;
156 case EXT2_IOC_SETVERSION:
157 - if (!is_owner_or_cap(inode))
158 - return -EPERM;
159 - if (IS_RDONLY(inode))
160 - return -EROFS;
161 - if (get_user(inode->i_generation, (int __user *) arg))
162 - return -EFAULT;
163 + if (!is_owner_or_cap(inode)) {
164 + retval = -EPERM;
165 + goto out;
167 + if (IS_RDONLY(inode)) {
168 + retval = -EROFS;
169 + goto out;
171 + if (get_user(inode->i_generation, (int __user *) arg)) {
172 + retval = -EFAULT;
173 + goto out;
175 inode->i_ctime = CURRENT_TIME_SEC;
176 mark_inode_dirty(inode);
177 - return 0;
178 + goto out;
179 case EXT2_IOC_GETRSVSZ:
180 if (test_opt(inode->i_sb, RESERVATION)
181 && S_ISREG(inode->i_mode)
182 && ei->i_block_alloc_info) {
183 rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
184 - return put_user(rsv_window_size, (int __user *)arg);
185 + retval = put_user(rsv_window_size, (int __user *)arg);
186 + goto out;
188 - return -ENOTTY;
189 + retval = -ENOTTY;
190 + goto out;
191 case EXT2_IOC_SETRSVSZ: {
193 - if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
194 - return -ENOTTY;
195 + if (!test_opt(inode->i_sb, RESERVATION) ||
196 + !S_ISREG(inode->i_mode)) {
197 + retval = -ENOTTY;
198 + goto out;
201 - if (IS_RDONLY(inode))
202 - return -EROFS;
203 + if (IS_RDONLY(inode)) {
204 + retval = -EROFS;
205 + goto out;
208 - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
209 - return -EACCES;
210 + if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) {
211 + retval = -EACCES;
212 + goto out;
215 - if (get_user(rsv_window_size, (int __user *)arg))
216 - return -EFAULT;
217 + if (get_user(rsv_window_size, (int __user *)arg)) {
218 + retval = -EFAULT;
219 + goto out;
222 if (rsv_window_size > EXT2_MAX_RESERVE_BLOCKS)
223 rsv_window_size = EXT2_MAX_RESERVE_BLOCKS;
224 @@ -131,11 +164,15 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
225 rsv->rsv_goal_size = rsv_window_size;
227 mutex_unlock(&ei->truncate_mutex);
228 - return 0;
229 + goto out;
231 default:
232 - return -ENOTTY;
233 + retval = -ENOTTY;
234 + goto out;
236 +out:
237 + unlock_kernel();
238 + return retval;
241 #ifdef CONFIG_COMPAT
242 @@ -161,9 +198,7 @@ long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
243 default:
244 return -ENOIOCTLCMD;
246 - lock_kernel();
247 ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
248 - unlock_kernel();
249 return ret;
251 #endif
253 1.5.3.8