diff options
Diffstat (limited to 'fs/ext3/ioctl.c')
-rw-r--r-- | fs/ext3/ioctl.c | 327 |
1 files changed, 0 insertions, 327 deletions
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c deleted file mode 100644 index 4d96e9a64532..000000000000 --- a/fs/ext3/ioctl.c +++ /dev/null | |||
@@ -1,327 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/ext3/ioctl.c | ||
3 | * | ||
4 | * Copyright (C) 1993, 1994, 1995 | ||
5 | * Remy Card (card@masi.ibp.fr) | ||
6 | * Laboratoire MASI - Institut Blaise Pascal | ||
7 | * Universite Pierre et Marie Curie (Paris VI) | ||
8 | */ | ||
9 | |||
10 | #include <linux/mount.h> | ||
11 | #include <linux/compat.h> | ||
12 | #include <asm/uaccess.h> | ||
13 | #include "ext3.h" | ||
14 | |||
15 | long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
16 | { | ||
17 | struct inode *inode = file_inode(filp); | ||
18 | struct ext3_inode_info *ei = EXT3_I(inode); | ||
19 | unsigned int flags; | ||
20 | unsigned short rsv_window_size; | ||
21 | |||
22 | ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg); | ||
23 | |||
24 | switch (cmd) { | ||
25 | case EXT3_IOC_GETFLAGS: | ||
26 | ext3_get_inode_flags(ei); | ||
27 | flags = ei->i_flags & EXT3_FL_USER_VISIBLE; | ||
28 | return put_user(flags, (int __user *) arg); | ||
29 | case EXT3_IOC_SETFLAGS: { | ||
30 | handle_t *handle = NULL; | ||
31 | int err; | ||
32 | struct ext3_iloc iloc; | ||
33 | unsigned int oldflags; | ||
34 | unsigned int jflag; | ||
35 | |||
36 | if (!inode_owner_or_capable(inode)) | ||
37 | return -EACCES; | ||
38 | |||
39 | if (get_user(flags, (int __user *) arg)) | ||
40 | return -EFAULT; | ||
41 | |||
42 | err = mnt_want_write_file(filp); | ||
43 | if (err) | ||
44 | return err; | ||
45 | |||
46 | flags = ext3_mask_flags(inode->i_mode, flags); | ||
47 | |||
48 | mutex_lock(&inode->i_mutex); | ||
49 | |||
50 | /* Is it quota file? Do not allow user to mess with it */ | ||
51 | err = -EPERM; | ||
52 | if (IS_NOQUOTA(inode)) | ||
53 | goto flags_out; | ||
54 | |||
55 | oldflags = ei->i_flags; | ||
56 | |||
57 | /* The JOURNAL_DATA flag is modifiable only by root */ | ||
58 | jflag = flags & EXT3_JOURNAL_DATA_FL; | ||
59 | |||
60 | /* | ||
61 | * The IMMUTABLE and APPEND_ONLY flags can only be changed by | ||
62 | * the relevant capability. | ||
63 | * | ||
64 | * This test looks nicer. Thanks to Pauline Middelink | ||
65 | */ | ||
66 | if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { | ||
67 | if (!capable(CAP_LINUX_IMMUTABLE)) | ||
68 | goto flags_out; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * The JOURNAL_DATA flag can only be changed by | ||
73 | * the relevant capability. | ||
74 | */ | ||
75 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) { | ||
76 | if (!capable(CAP_SYS_RESOURCE)) | ||
77 | goto flags_out; | ||
78 | } | ||
79 | |||
80 | handle = ext3_journal_start(inode, 1); | ||
81 | if (IS_ERR(handle)) { | ||
82 | err = PTR_ERR(handle); | ||
83 | goto flags_out; | ||
84 | } | ||
85 | if (IS_SYNC(inode)) | ||
86 | handle->h_sync = 1; | ||
87 | err = ext3_reserve_inode_write(handle, inode, &iloc); | ||
88 | if (err) | ||
89 | goto flags_err; | ||
90 | |||
91 | flags = flags & EXT3_FL_USER_MODIFIABLE; | ||
92 | flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE; | ||
93 | ei->i_flags = flags; | ||
94 | |||
95 | ext3_set_inode_flags(inode); | ||
96 | inode->i_ctime = CURRENT_TIME_SEC; | ||
97 | |||
98 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); | ||
99 | flags_err: | ||
100 | ext3_journal_stop(handle); | ||
101 | if (err) | ||
102 | goto flags_out; | ||
103 | |||
104 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) | ||
105 | err = ext3_change_inode_journal_flag(inode, jflag); | ||
106 | flags_out: | ||
107 | mutex_unlock(&inode->i_mutex); | ||
108 | mnt_drop_write_file(filp); | ||
109 | return err; | ||
110 | } | ||
111 | case EXT3_IOC_GETVERSION: | ||
112 | case EXT3_IOC_GETVERSION_OLD: | ||
113 | return put_user(inode->i_generation, (int __user *) arg); | ||
114 | case EXT3_IOC_SETVERSION: | ||
115 | case EXT3_IOC_SETVERSION_OLD: { | ||
116 | handle_t *handle; | ||
117 | struct ext3_iloc iloc; | ||
118 | __u32 generation; | ||
119 | int err; | ||
120 | |||
121 | if (!inode_owner_or_capable(inode)) | ||
122 | return -EPERM; | ||
123 | |||
124 | err = mnt_want_write_file(filp); | ||
125 | if (err) | ||
126 | return err; | ||
127 | if (get_user(generation, (int __user *) arg)) { | ||
128 | err = -EFAULT; | ||
129 | goto setversion_out; | ||
130 | } | ||
131 | |||
132 | mutex_lock(&inode->i_mutex); | ||
133 | handle = ext3_journal_start(inode, 1); | ||
134 | if (IS_ERR(handle)) { | ||
135 | err = PTR_ERR(handle); | ||
136 | goto unlock_out; | ||
137 | } | ||
138 | err = ext3_reserve_inode_write(handle, inode, &iloc); | ||
139 | if (err == 0) { | ||
140 | inode->i_ctime = CURRENT_TIME_SEC; | ||
141 | inode->i_generation = generation; | ||
142 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); | ||
143 | } | ||
144 | ext3_journal_stop(handle); | ||
145 | |||
146 | unlock_out: | ||
147 | mutex_unlock(&inode->i_mutex); | ||
148 | setversion_out: | ||
149 | mnt_drop_write_file(filp); | ||
150 | return err; | ||
151 | } | ||
152 | case EXT3_IOC_GETRSVSZ: | ||
153 | if (test_opt(inode->i_sb, RESERVATION) | ||
154 | && S_ISREG(inode->i_mode) | ||
155 | && ei->i_block_alloc_info) { | ||
156 | rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size; | ||
157 | return put_user(rsv_window_size, (int __user *)arg); | ||
158 | } | ||
159 | return -ENOTTY; | ||
160 | case EXT3_IOC_SETRSVSZ: { | ||
161 | int err; | ||
162 | |||
163 | if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) | ||
164 | return -ENOTTY; | ||
165 | |||
166 | err = mnt_want_write_file(filp); | ||
167 | if (err) | ||
168 | return err; | ||
169 | |||
170 | if (!inode_owner_or_capable(inode)) { | ||
171 | err = -EACCES; | ||
172 | goto setrsvsz_out; | ||
173 | } | ||
174 | |||
175 | if (get_user(rsv_window_size, (int __user *)arg)) { | ||
176 | err = -EFAULT; | ||
177 | goto setrsvsz_out; | ||
178 | } | ||
179 | |||
180 | if (rsv_window_size > EXT3_MAX_RESERVE_BLOCKS) | ||
181 | rsv_window_size = EXT3_MAX_RESERVE_BLOCKS; | ||
182 | |||
183 | /* | ||
184 | * need to allocate reservation structure for this inode | ||
185 | * before set the window size | ||
186 | */ | ||
187 | mutex_lock(&ei->truncate_mutex); | ||
188 | if (!ei->i_block_alloc_info) | ||
189 | ext3_init_block_alloc_info(inode); | ||
190 | |||
191 | if (ei->i_block_alloc_info){ | ||
192 | struct ext3_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node; | ||
193 | rsv->rsv_goal_size = rsv_window_size; | ||
194 | } | ||
195 | mutex_unlock(&ei->truncate_mutex); | ||
196 | setrsvsz_out: | ||
197 | mnt_drop_write_file(filp); | ||
198 | return err; | ||
199 | } | ||
200 | case EXT3_IOC_GROUP_EXTEND: { | ||
201 | ext3_fsblk_t n_blocks_count; | ||
202 | struct super_block *sb = inode->i_sb; | ||
203 | int err, err2; | ||
204 | |||
205 | if (!capable(CAP_SYS_RESOURCE)) | ||
206 | return -EPERM; | ||
207 | |||
208 | err = mnt_want_write_file(filp); | ||
209 | if (err) | ||
210 | return err; | ||
211 | |||
212 | if (get_user(n_blocks_count, (__u32 __user *)arg)) { | ||
213 | err = -EFAULT; | ||
214 | goto group_extend_out; | ||
215 | } | ||
216 | err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count); | ||
217 | journal_lock_updates(EXT3_SB(sb)->s_journal); | ||
218 | err2 = journal_flush(EXT3_SB(sb)->s_journal); | ||
219 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | ||
220 | if (err == 0) | ||
221 | err = err2; | ||
222 | group_extend_out: | ||
223 | mnt_drop_write_file(filp); | ||
224 | return err; | ||
225 | } | ||
226 | case EXT3_IOC_GROUP_ADD: { | ||
227 | struct ext3_new_group_data input; | ||
228 | struct super_block *sb = inode->i_sb; | ||
229 | int err, err2; | ||
230 | |||
231 | if (!capable(CAP_SYS_RESOURCE)) | ||
232 | return -EPERM; | ||
233 | |||
234 | err = mnt_want_write_file(filp); | ||
235 | if (err) | ||
236 | return err; | ||
237 | |||
238 | if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg, | ||
239 | sizeof(input))) { | ||
240 | err = -EFAULT; | ||
241 | goto group_add_out; | ||
242 | } | ||
243 | |||
244 | err = ext3_group_add(sb, &input); | ||
245 | journal_lock_updates(EXT3_SB(sb)->s_journal); | ||
246 | err2 = journal_flush(EXT3_SB(sb)->s_journal); | ||
247 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | ||
248 | if (err == 0) | ||
249 | err = err2; | ||
250 | group_add_out: | ||
251 | mnt_drop_write_file(filp); | ||
252 | return err; | ||
253 | } | ||
254 | case FITRIM: { | ||
255 | |||
256 | struct super_block *sb = inode->i_sb; | ||
257 | struct fstrim_range range; | ||
258 | int ret = 0; | ||
259 | |||
260 | if (!capable(CAP_SYS_ADMIN)) | ||
261 | return -EPERM; | ||
262 | |||
263 | if (copy_from_user(&range, (struct fstrim_range __user *)arg, | ||
264 | sizeof(range))) | ||
265 | return -EFAULT; | ||
266 | |||
267 | ret = ext3_trim_fs(sb, &range); | ||
268 | if (ret < 0) | ||
269 | return ret; | ||
270 | |||
271 | if (copy_to_user((struct fstrim_range __user *)arg, &range, | ||
272 | sizeof(range))) | ||
273 | return -EFAULT; | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | default: | ||
279 | return -ENOTTY; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | #ifdef CONFIG_COMPAT | ||
284 | long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
285 | { | ||
286 | /* These are just misnamed, they actually get/put from/to user an int */ | ||
287 | switch (cmd) { | ||
288 | case EXT3_IOC32_GETFLAGS: | ||
289 | cmd = EXT3_IOC_GETFLAGS; | ||
290 | break; | ||
291 | case EXT3_IOC32_SETFLAGS: | ||
292 | cmd = EXT3_IOC_SETFLAGS; | ||
293 | break; | ||
294 | case EXT3_IOC32_GETVERSION: | ||
295 | cmd = EXT3_IOC_GETVERSION; | ||
296 | break; | ||
297 | case EXT3_IOC32_SETVERSION: | ||
298 | cmd = EXT3_IOC_SETVERSION; | ||
299 | break; | ||
300 | case EXT3_IOC32_GROUP_EXTEND: | ||
301 | cmd = EXT3_IOC_GROUP_EXTEND; | ||
302 | break; | ||
303 | case EXT3_IOC32_GETVERSION_OLD: | ||
304 | cmd = EXT3_IOC_GETVERSION_OLD; | ||
305 | break; | ||
306 | case EXT3_IOC32_SETVERSION_OLD: | ||
307 | cmd = EXT3_IOC_SETVERSION_OLD; | ||
308 | break; | ||
309 | #ifdef CONFIG_JBD_DEBUG | ||
310 | case EXT3_IOC32_WAIT_FOR_READONLY: | ||
311 | cmd = EXT3_IOC_WAIT_FOR_READONLY; | ||
312 | break; | ||
313 | #endif | ||
314 | case EXT3_IOC32_GETRSVSZ: | ||
315 | cmd = EXT3_IOC_GETRSVSZ; | ||
316 | break; | ||
317 | case EXT3_IOC32_SETRSVSZ: | ||
318 | cmd = EXT3_IOC_SETRSVSZ; | ||
319 | break; | ||
320 | case EXT3_IOC_GROUP_ADD: | ||
321 | break; | ||
322 | default: | ||
323 | return -ENOIOCTLCMD; | ||
324 | } | ||
325 | return ext3_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); | ||
326 | } | ||
327 | #endif | ||