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