1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * linux/fs/ext4/ioctl.c |
4 | * |
5 | * Copyright (C) 1993, 1994, 1995 |
6 | * Remy Card (card@masi.ibp.fr) |
7 | * Laboratoire MASI - Institut Blaise Pascal |
8 | * Universite Pierre et Marie Curie (Paris VI) |
9 | */ |
10 | |
11 | #include <linux/fs.h> |
12 | #include <linux/capability.h> |
13 | #include <linux/time.h> |
14 | #include <linux/compat.h> |
15 | #include <linux/mount.h> |
16 | #include <linux/file.h> |
17 | #include <linux/quotaops.h> |
18 | #include <linux/random.h> |
19 | #include <linux/uaccess.h> |
20 | #include <linux/delay.h> |
21 | #include <linux/iversion.h> |
22 | #include <linux/fileattr.h> |
23 | #include <linux/uuid.h> |
24 | #include "ext4_jbd2.h" |
25 | #include "ext4.h" |
26 | #include <linux/fsmap.h> |
27 | #include "fsmap.h" |
28 | #include <trace/events/ext4.h> |
29 | |
30 | typedef void ext4_update_sb_callback(struct ext4_super_block *es, |
31 | const void *arg); |
32 | |
33 | /* |
34 | * Superblock modification callback function for changing file system |
35 | * label |
36 | */ |
37 | static void ext4_sb_setlabel(struct ext4_super_block *es, const void *arg) |
38 | { |
39 | /* Sanity check, this should never happen */ |
40 | BUILD_BUG_ON(sizeof(es->s_volume_name) < EXT4_LABEL_MAX); |
41 | |
42 | memcpy(es->s_volume_name, (char *)arg, EXT4_LABEL_MAX); |
43 | } |
44 | |
45 | /* |
46 | * Superblock modification callback function for changing file system |
47 | * UUID. |
48 | */ |
49 | static void ext4_sb_setuuid(struct ext4_super_block *es, const void *arg) |
50 | { |
51 | memcpy(es->s_uuid, (__u8 *)arg, UUID_SIZE); |
52 | } |
53 | |
54 | static |
55 | int ext4_update_primary_sb(struct super_block *sb, handle_t *handle, |
56 | ext4_update_sb_callback func, |
57 | const void *arg) |
58 | { |
59 | int err = 0; |
60 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
61 | struct buffer_head *bh = sbi->s_sbh; |
62 | struct ext4_super_block *es = sbi->s_es; |
63 | |
64 | trace_ext4_update_sb(sb, fsblk: bh->b_blocknr, flags: 1); |
65 | |
66 | BUFFER_TRACE(bh, "get_write_access" ); |
67 | err = ext4_journal_get_write_access(handle, sb, |
68 | bh, |
69 | EXT4_JTR_NONE); |
70 | if (err) |
71 | goto out_err; |
72 | |
73 | lock_buffer(bh); |
74 | func(es, arg); |
75 | ext4_superblock_csum_set(sb); |
76 | unlock_buffer(bh); |
77 | |
78 | if (buffer_write_io_error(bh) || !buffer_uptodate(bh)) { |
79 | ext4_msg(sbi->s_sb, KERN_ERR, "previous I/O error to " |
80 | "superblock detected" ); |
81 | clear_buffer_write_io_error(bh); |
82 | set_buffer_uptodate(bh); |
83 | } |
84 | |
85 | err = ext4_handle_dirty_metadata(handle, NULL, bh); |
86 | if (err) |
87 | goto out_err; |
88 | err = sync_dirty_buffer(bh); |
89 | out_err: |
90 | ext4_std_error(sb, err); |
91 | return err; |
92 | } |
93 | |
94 | /* |
95 | * Update one backup superblock in the group 'grp' using the callback |
96 | * function 'func' and argument 'arg'. If the handle is NULL the |
97 | * modification is not journalled. |
98 | * |
99 | * Returns: 0 when no modification was done (no superblock in the group) |
100 | * 1 when the modification was successful |
101 | * <0 on error |
102 | */ |
103 | static int ext4_update_backup_sb(struct super_block *sb, |
104 | handle_t *handle, ext4_group_t grp, |
105 | ext4_update_sb_callback func, const void *arg) |
106 | { |
107 | int err = 0; |
108 | ext4_fsblk_t sb_block; |
109 | struct buffer_head *bh; |
110 | unsigned long offset = 0; |
111 | struct ext4_super_block *es; |
112 | |
113 | if (!ext4_bg_has_super(sb, group: grp)) |
114 | return 0; |
115 | |
116 | /* |
117 | * For the group 0 there is always 1k padding, so we have |
118 | * either adjust offset, or sb_block depending on blocksize |
119 | */ |
120 | if (grp == 0) { |
121 | sb_block = 1 * EXT4_MIN_BLOCK_SIZE; |
122 | offset = do_div(sb_block, sb->s_blocksize); |
123 | } else { |
124 | sb_block = ext4_group_first_block_no(sb, group_no: grp); |
125 | offset = 0; |
126 | } |
127 | |
128 | trace_ext4_update_sb(sb, fsblk: sb_block, flags: handle ? 1 : 0); |
129 | |
130 | bh = ext4_sb_bread(sb, block: sb_block, op_flags: 0); |
131 | if (IS_ERR(ptr: bh)) |
132 | return PTR_ERR(ptr: bh); |
133 | |
134 | if (handle) { |
135 | BUFFER_TRACE(bh, "get_write_access" ); |
136 | err = ext4_journal_get_write_access(handle, sb, |
137 | bh, |
138 | EXT4_JTR_NONE); |
139 | if (err) |
140 | goto out_bh; |
141 | } |
142 | |
143 | es = (struct ext4_super_block *) (bh->b_data + offset); |
144 | lock_buffer(bh); |
145 | if (ext4_has_metadata_csum(sb) && |
146 | es->s_checksum != ext4_superblock_csum(sb, es)) { |
147 | ext4_msg(sb, KERN_ERR, "Invalid checksum for backup " |
148 | "superblock %llu" , sb_block); |
149 | unlock_buffer(bh); |
150 | goto out_bh; |
151 | } |
152 | func(es, arg); |
153 | if (ext4_has_metadata_csum(sb)) |
154 | es->s_checksum = ext4_superblock_csum(sb, es); |
155 | set_buffer_uptodate(bh); |
156 | unlock_buffer(bh); |
157 | |
158 | if (handle) { |
159 | err = ext4_handle_dirty_metadata(handle, NULL, bh); |
160 | if (err) |
161 | goto out_bh; |
162 | } else { |
163 | BUFFER_TRACE(bh, "marking dirty" ); |
164 | mark_buffer_dirty(bh); |
165 | } |
166 | err = sync_dirty_buffer(bh); |
167 | |
168 | out_bh: |
169 | brelse(bh); |
170 | ext4_std_error(sb, err); |
171 | return (err) ? err : 1; |
172 | } |
173 | |
174 | /* |
175 | * Update primary and backup superblocks using the provided function |
176 | * func and argument arg. |
177 | * |
178 | * Only the primary superblock and at most two backup superblock |
179 | * modifications are journalled; the rest is modified without journal. |
180 | * This is safe because e2fsck will re-write them if there is a problem, |
181 | * and we're very unlikely to ever need more than two backups. |
182 | */ |
183 | static |
184 | int ext4_update_superblocks_fn(struct super_block *sb, |
185 | ext4_update_sb_callback func, |
186 | const void *arg) |
187 | { |
188 | handle_t *handle; |
189 | ext4_group_t ngroups; |
190 | unsigned int three = 1; |
191 | unsigned int five = 5; |
192 | unsigned int seven = 7; |
193 | int err = 0, ret, i; |
194 | ext4_group_t grp, primary_grp; |
195 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
196 | |
197 | /* |
198 | * We can't update superblocks while the online resize is running |
199 | */ |
200 | if (test_and_set_bit_lock(EXT4_FLAGS_RESIZING, |
201 | addr: &sbi->s_ext4_flags)) { |
202 | ext4_msg(sb, KERN_ERR, "Can't modify superblock while" |
203 | "performing online resize" ); |
204 | return -EBUSY; |
205 | } |
206 | |
207 | /* |
208 | * We're only going to update primary superblock and two |
209 | * backup superblocks in this transaction. |
210 | */ |
211 | handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 3); |
212 | if (IS_ERR(ptr: handle)) { |
213 | err = PTR_ERR(ptr: handle); |
214 | goto out; |
215 | } |
216 | |
217 | /* Update primary superblock */ |
218 | err = ext4_update_primary_sb(sb, handle, func, arg); |
219 | if (err) { |
220 | ext4_msg(sb, KERN_ERR, "Failed to update primary " |
221 | "superblock" ); |
222 | goto out_journal; |
223 | } |
224 | |
225 | primary_grp = ext4_get_group_number(sb, block: sbi->s_sbh->b_blocknr); |
226 | ngroups = ext4_get_groups_count(sb); |
227 | |
228 | /* |
229 | * Update backup superblocks. We have to start from group 0 |
230 | * because it might not be where the primary superblock is |
231 | * if the fs is mounted with -o sb=<backup_sb_block> |
232 | */ |
233 | i = 0; |
234 | grp = 0; |
235 | while (grp < ngroups) { |
236 | /* Skip primary superblock */ |
237 | if (grp == primary_grp) |
238 | goto next_grp; |
239 | |
240 | ret = ext4_update_backup_sb(sb, handle, grp, func, arg); |
241 | if (ret < 0) { |
242 | /* Ignore bad checksum; try to update next sb */ |
243 | if (ret == -EFSBADCRC) |
244 | goto next_grp; |
245 | err = ret; |
246 | goto out_journal; |
247 | } |
248 | |
249 | i += ret; |
250 | if (handle && i > 1) { |
251 | /* |
252 | * We're only journalling primary superblock and |
253 | * two backup superblocks; the rest is not |
254 | * journalled. |
255 | */ |
256 | err = ext4_journal_stop(handle); |
257 | if (err) |
258 | goto out; |
259 | handle = NULL; |
260 | } |
261 | next_grp: |
262 | grp = ext4_list_backups(sb, three: &three, five: &five, seven: &seven); |
263 | } |
264 | |
265 | out_journal: |
266 | if (handle) { |
267 | ret = ext4_journal_stop(handle); |
268 | if (ret && !err) |
269 | err = ret; |
270 | } |
271 | out: |
272 | clear_bit_unlock(EXT4_FLAGS_RESIZING, addr: &sbi->s_ext4_flags); |
273 | smp_mb__after_atomic(); |
274 | return err ? err : 0; |
275 | } |
276 | |
277 | /* |
278 | * Swap memory between @a and @b for @len bytes. |
279 | * |
280 | * @a: pointer to first memory area |
281 | * @b: pointer to second memory area |
282 | * @len: number of bytes to swap |
283 | * |
284 | */ |
285 | static void memswap(void *a, void *b, size_t len) |
286 | { |
287 | unsigned char *ap, *bp; |
288 | |
289 | ap = (unsigned char *)a; |
290 | bp = (unsigned char *)b; |
291 | while (len-- > 0) { |
292 | swap(*ap, *bp); |
293 | ap++; |
294 | bp++; |
295 | } |
296 | } |
297 | |
298 | /* |
299 | * Swap i_data and associated attributes between @inode1 and @inode2. |
300 | * This function is used for the primary swap between inode1 and inode2 |
301 | * and also to revert this primary swap in case of errors. |
302 | * |
303 | * Therefore you have to make sure, that calling this method twice |
304 | * will revert all changes. |
305 | * |
306 | * @inode1: pointer to first inode |
307 | * @inode2: pointer to second inode |
308 | */ |
309 | static void swap_inode_data(struct inode *inode1, struct inode *inode2) |
310 | { |
311 | loff_t isize; |
312 | struct ext4_inode_info *ei1; |
313 | struct ext4_inode_info *ei2; |
314 | unsigned long tmp; |
315 | struct timespec64 ts1, ts2; |
316 | |
317 | ei1 = EXT4_I(inode1); |
318 | ei2 = EXT4_I(inode2); |
319 | |
320 | swap(inode1->i_version, inode2->i_version); |
321 | |
322 | ts1 = inode_get_atime(inode: inode1); |
323 | ts2 = inode_get_atime(inode: inode2); |
324 | inode_set_atime_to_ts(inode: inode1, ts: ts2); |
325 | inode_set_atime_to_ts(inode: inode2, ts: ts1); |
326 | |
327 | ts1 = inode_get_mtime(inode: inode1); |
328 | ts2 = inode_get_mtime(inode: inode2); |
329 | inode_set_mtime_to_ts(inode: inode1, ts: ts2); |
330 | inode_set_mtime_to_ts(inode: inode2, ts: ts1); |
331 | |
332 | memswap(a: ei1->i_data, b: ei2->i_data, len: sizeof(ei1->i_data)); |
333 | tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP; |
334 | ei1->i_flags = (ei2->i_flags & EXT4_FL_SHOULD_SWAP) | |
335 | (ei1->i_flags & ~EXT4_FL_SHOULD_SWAP); |
336 | ei2->i_flags = tmp | (ei2->i_flags & ~EXT4_FL_SHOULD_SWAP); |
337 | swap(ei1->i_disksize, ei2->i_disksize); |
338 | ext4_es_remove_extent(inode: inode1, lblk: 0, EXT_MAX_BLOCKS); |
339 | ext4_es_remove_extent(inode: inode2, lblk: 0, EXT_MAX_BLOCKS); |
340 | |
341 | isize = i_size_read(inode: inode1); |
342 | i_size_write(inode: inode1, i_size: i_size_read(inode: inode2)); |
343 | i_size_write(inode: inode2, i_size: isize); |
344 | } |
345 | |
346 | void ext4_reset_inode_seed(struct inode *inode) |
347 | { |
348 | struct ext4_inode_info *ei = EXT4_I(inode); |
349 | struct ext4_sb_info *sbi = EXT4_SB(sb: inode->i_sb); |
350 | __le32 inum = cpu_to_le32(inode->i_ino); |
351 | __le32 gen = cpu_to_le32(inode->i_generation); |
352 | __u32 csum; |
353 | |
354 | if (!ext4_has_metadata_csum(sb: inode->i_sb)) |
355 | return; |
356 | |
357 | csum = ext4_chksum(sbi, crc: sbi->s_csum_seed, address: (__u8 *)&inum, length: sizeof(inum)); |
358 | ei->i_csum_seed = ext4_chksum(sbi, crc: csum, address: (__u8 *)&gen, length: sizeof(gen)); |
359 | } |
360 | |
361 | /* |
362 | * Swap the information from the given @inode and the inode |
363 | * EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other |
364 | * important fields of the inodes. |
365 | * |
366 | * @sb: the super block of the filesystem |
367 | * @idmap: idmap of the mount the inode was found from |
368 | * @inode: the inode to swap with EXT4_BOOT_LOADER_INO |
369 | * |
370 | */ |
371 | static long swap_inode_boot_loader(struct super_block *sb, |
372 | struct mnt_idmap *idmap, |
373 | struct inode *inode) |
374 | { |
375 | handle_t *handle; |
376 | int err; |
377 | struct inode *inode_bl; |
378 | struct ext4_inode_info *ei_bl; |
379 | qsize_t size, size_bl, diff; |
380 | blkcnt_t blocks; |
381 | unsigned short bytes; |
382 | |
383 | inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, |
384 | EXT4_IGET_SPECIAL | EXT4_IGET_BAD); |
385 | if (IS_ERR(ptr: inode_bl)) |
386 | return PTR_ERR(ptr: inode_bl); |
387 | ei_bl = EXT4_I(inode_bl); |
388 | |
389 | /* Protect orig inodes against a truncate and make sure, |
390 | * that only 1 swap_inode_boot_loader is running. */ |
391 | lock_two_nondirectories(inode, inode_bl); |
392 | |
393 | if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) || |
394 | IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) || |
395 | (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) || |
396 | ext4_has_inline_data(inode)) { |
397 | err = -EINVAL; |
398 | goto journal_err_out; |
399 | } |
400 | |
401 | if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) || |
402 | !inode_owner_or_capable(idmap, inode) || |
403 | !capable(CAP_SYS_ADMIN)) { |
404 | err = -EPERM; |
405 | goto journal_err_out; |
406 | } |
407 | |
408 | filemap_invalidate_lock(mapping: inode->i_mapping); |
409 | err = filemap_write_and_wait(mapping: inode->i_mapping); |
410 | if (err) |
411 | goto err_out; |
412 | |
413 | err = filemap_write_and_wait(mapping: inode_bl->i_mapping); |
414 | if (err) |
415 | goto err_out; |
416 | |
417 | /* Wait for all existing dio workers */ |
418 | inode_dio_wait(inode); |
419 | inode_dio_wait(inode: inode_bl); |
420 | |
421 | truncate_inode_pages(&inode->i_data, 0); |
422 | truncate_inode_pages(&inode_bl->i_data, 0); |
423 | |
424 | handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2); |
425 | if (IS_ERR(ptr: handle)) { |
426 | err = -EINVAL; |
427 | goto err_out; |
428 | } |
429 | ext4_fc_mark_ineligible(sb, reason: EXT4_FC_REASON_SWAP_BOOT, handle); |
430 | |
431 | /* Protect extent tree against block allocations via delalloc */ |
432 | ext4_double_down_write_data_sem(first: inode, second: inode_bl); |
433 | |
434 | if (is_bad_inode(inode_bl) || !S_ISREG(inode_bl->i_mode)) { |
435 | /* this inode has never been used as a BOOT_LOADER */ |
436 | set_nlink(inode: inode_bl, nlink: 1); |
437 | i_uid_write(inode: inode_bl, uid: 0); |
438 | i_gid_write(inode: inode_bl, gid: 0); |
439 | inode_bl->i_flags = 0; |
440 | ei_bl->i_flags = 0; |
441 | inode_set_iversion(inode: inode_bl, val: 1); |
442 | i_size_write(inode: inode_bl, i_size: 0); |
443 | EXT4_I(inode_bl)->i_disksize = inode_bl->i_size; |
444 | inode_bl->i_mode = S_IFREG; |
445 | if (ext4_has_feature_extents(sb)) { |
446 | ext4_set_inode_flag(inode: inode_bl, bit: EXT4_INODE_EXTENTS); |
447 | ext4_ext_tree_init(handle, inode: inode_bl); |
448 | } else |
449 | memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data)); |
450 | } |
451 | |
452 | err = dquot_initialize(inode); |
453 | if (err) |
454 | goto err_out1; |
455 | |
456 | size = (qsize_t)(inode->i_blocks) * (1 << 9) + inode->i_bytes; |
457 | size_bl = (qsize_t)(inode_bl->i_blocks) * (1 << 9) + inode_bl->i_bytes; |
458 | diff = size - size_bl; |
459 | swap_inode_data(inode1: inode, inode2: inode_bl); |
460 | |
461 | inode_set_ctime_current(inode); |
462 | inode_set_ctime_current(inode: inode_bl); |
463 | inode_inc_iversion(inode); |
464 | |
465 | inode->i_generation = get_random_u32(); |
466 | inode_bl->i_generation = get_random_u32(); |
467 | ext4_reset_inode_seed(inode); |
468 | ext4_reset_inode_seed(inode: inode_bl); |
469 | |
470 | ext4_discard_preallocations(inode); |
471 | |
472 | err = ext4_mark_inode_dirty(handle, inode); |
473 | if (err < 0) { |
474 | /* No need to update quota information. */ |
475 | ext4_warning(inode->i_sb, |
476 | "couldn't mark inode #%lu dirty (err %d)" , |
477 | inode->i_ino, err); |
478 | /* Revert all changes: */ |
479 | swap_inode_data(inode1: inode, inode2: inode_bl); |
480 | ext4_mark_inode_dirty(handle, inode); |
481 | goto err_out1; |
482 | } |
483 | |
484 | blocks = inode_bl->i_blocks; |
485 | bytes = inode_bl->i_bytes; |
486 | inode_bl->i_blocks = inode->i_blocks; |
487 | inode_bl->i_bytes = inode->i_bytes; |
488 | err = ext4_mark_inode_dirty(handle, inode_bl); |
489 | if (err < 0) { |
490 | /* No need to update quota information. */ |
491 | ext4_warning(inode_bl->i_sb, |
492 | "couldn't mark inode #%lu dirty (err %d)" , |
493 | inode_bl->i_ino, err); |
494 | goto revert; |
495 | } |
496 | |
497 | /* Bootloader inode should not be counted into quota information. */ |
498 | if (diff > 0) |
499 | dquot_free_space(inode, nr: diff); |
500 | else |
501 | err = dquot_alloc_space(inode, nr: -1 * diff); |
502 | |
503 | if (err < 0) { |
504 | revert: |
505 | /* Revert all changes: */ |
506 | inode_bl->i_blocks = blocks; |
507 | inode_bl->i_bytes = bytes; |
508 | swap_inode_data(inode1: inode, inode2: inode_bl); |
509 | ext4_mark_inode_dirty(handle, inode); |
510 | ext4_mark_inode_dirty(handle, inode_bl); |
511 | } |
512 | |
513 | err_out1: |
514 | ext4_journal_stop(handle); |
515 | ext4_double_up_write_data_sem(orig_inode: inode, donor_inode: inode_bl); |
516 | |
517 | err_out: |
518 | filemap_invalidate_unlock(mapping: inode->i_mapping); |
519 | journal_err_out: |
520 | unlock_two_nondirectories(inode, inode_bl); |
521 | iput(inode_bl); |
522 | return err; |
523 | } |
524 | |
525 | /* |
526 | * If immutable is set and we are not clearing it, we're not allowed to change |
527 | * anything else in the inode. Don't error out if we're only trying to set |
528 | * immutable on an immutable file. |
529 | */ |
530 | static int ext4_ioctl_check_immutable(struct inode *inode, __u32 new_projid, |
531 | unsigned int flags) |
532 | { |
533 | struct ext4_inode_info *ei = EXT4_I(inode); |
534 | unsigned int oldflags = ei->i_flags; |
535 | |
536 | if (!(oldflags & EXT4_IMMUTABLE_FL) || !(flags & EXT4_IMMUTABLE_FL)) |
537 | return 0; |
538 | |
539 | if ((oldflags & ~EXT4_IMMUTABLE_FL) != (flags & ~EXT4_IMMUTABLE_FL)) |
540 | return -EPERM; |
541 | if (ext4_has_feature_project(sb: inode->i_sb) && |
542 | __kprojid_val(projid: ei->i_projid) != new_projid) |
543 | return -EPERM; |
544 | |
545 | return 0; |
546 | } |
547 | |
548 | static void ext4_dax_dontcache(struct inode *inode, unsigned int flags) |
549 | { |
550 | struct ext4_inode_info *ei = EXT4_I(inode); |
551 | |
552 | if (S_ISDIR(inode->i_mode)) |
553 | return; |
554 | |
555 | if (test_opt2(inode->i_sb, DAX_NEVER) || |
556 | test_opt(inode->i_sb, DAX_ALWAYS)) |
557 | return; |
558 | |
559 | if ((ei->i_flags ^ flags) & EXT4_DAX_FL) |
560 | d_mark_dontcache(inode); |
561 | } |
562 | |
563 | static bool dax_compatible(struct inode *inode, unsigned int oldflags, |
564 | unsigned int flags) |
565 | { |
566 | /* Allow the DAX flag to be changed on inline directories */ |
567 | if (S_ISDIR(inode->i_mode)) { |
568 | flags &= ~EXT4_INLINE_DATA_FL; |
569 | oldflags &= ~EXT4_INLINE_DATA_FL; |
570 | } |
571 | |
572 | if (flags & EXT4_DAX_FL) { |
573 | if ((oldflags & EXT4_DAX_MUT_EXCL) || |
574 | ext4_test_inode_state(inode, |
575 | bit: EXT4_STATE_VERITY_IN_PROGRESS)) { |
576 | return false; |
577 | } |
578 | } |
579 | |
580 | if ((flags & EXT4_DAX_MUT_EXCL) && (oldflags & EXT4_DAX_FL)) |
581 | return false; |
582 | |
583 | return true; |
584 | } |
585 | |
586 | static int ext4_ioctl_setflags(struct inode *inode, |
587 | unsigned int flags) |
588 | { |
589 | struct ext4_inode_info *ei = EXT4_I(inode); |
590 | handle_t *handle = NULL; |
591 | int err = -EPERM, migrate = 0; |
592 | struct ext4_iloc iloc; |
593 | unsigned int oldflags, mask, i; |
594 | struct super_block *sb = inode->i_sb; |
595 | |
596 | /* Is it quota file? Do not allow user to mess with it */ |
597 | if (ext4_is_quota_file(inode)) |
598 | goto flags_out; |
599 | |
600 | oldflags = ei->i_flags; |
601 | /* |
602 | * The JOURNAL_DATA flag can only be changed by |
603 | * the relevant capability. |
604 | */ |
605 | if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { |
606 | if (!capable(CAP_SYS_RESOURCE)) |
607 | goto flags_out; |
608 | } |
609 | |
610 | if (!dax_compatible(inode, oldflags, flags)) { |
611 | err = -EOPNOTSUPP; |
612 | goto flags_out; |
613 | } |
614 | |
615 | if ((flags ^ oldflags) & EXT4_EXTENTS_FL) |
616 | migrate = 1; |
617 | |
618 | if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) { |
619 | if (!ext4_has_feature_casefold(sb)) { |
620 | err = -EOPNOTSUPP; |
621 | goto flags_out; |
622 | } |
623 | |
624 | if (!S_ISDIR(inode->i_mode)) { |
625 | err = -ENOTDIR; |
626 | goto flags_out; |
627 | } |
628 | |
629 | if (!ext4_empty_dir(inode)) { |
630 | err = -ENOTEMPTY; |
631 | goto flags_out; |
632 | } |
633 | } |
634 | |
635 | /* |
636 | * Wait for all pending directio and then flush all the dirty pages |
637 | * for this file. The flush marks all the pages readonly, so any |
638 | * subsequent attempt to write to the file (particularly mmap pages) |
639 | * will come through the filesystem and fail. |
640 | */ |
641 | if (S_ISREG(inode->i_mode) && !IS_IMMUTABLE(inode) && |
642 | (flags & EXT4_IMMUTABLE_FL)) { |
643 | inode_dio_wait(inode); |
644 | err = filemap_write_and_wait(mapping: inode->i_mapping); |
645 | if (err) |
646 | goto flags_out; |
647 | } |
648 | |
649 | handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); |
650 | if (IS_ERR(ptr: handle)) { |
651 | err = PTR_ERR(ptr: handle); |
652 | goto flags_out; |
653 | } |
654 | if (IS_SYNC(inode)) |
655 | ext4_handle_sync(handle); |
656 | err = ext4_reserve_inode_write(handle, inode, iloc: &iloc); |
657 | if (err) |
658 | goto flags_err; |
659 | |
660 | ext4_dax_dontcache(inode, flags); |
661 | |
662 | for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { |
663 | if (!(mask & EXT4_FL_USER_MODIFIABLE)) |
664 | continue; |
665 | /* These flags get special treatment later */ |
666 | if (mask == EXT4_JOURNAL_DATA_FL || mask == EXT4_EXTENTS_FL) |
667 | continue; |
668 | if (mask & flags) |
669 | ext4_set_inode_flag(inode, bit: i); |
670 | else |
671 | ext4_clear_inode_flag(inode, bit: i); |
672 | } |
673 | |
674 | ext4_set_inode_flags(inode, init: false); |
675 | |
676 | inode_set_ctime_current(inode); |
677 | inode_inc_iversion(inode); |
678 | |
679 | err = ext4_mark_iloc_dirty(handle, inode, iloc: &iloc); |
680 | flags_err: |
681 | ext4_journal_stop(handle); |
682 | if (err) |
683 | goto flags_out; |
684 | |
685 | if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { |
686 | /* |
687 | * Changes to the journaling mode can cause unsafe changes to |
688 | * S_DAX if the inode is DAX |
689 | */ |
690 | if (IS_DAX(inode)) { |
691 | err = -EBUSY; |
692 | goto flags_out; |
693 | } |
694 | |
695 | err = ext4_change_inode_journal_flag(inode, |
696 | flags & EXT4_JOURNAL_DATA_FL); |
697 | if (err) |
698 | goto flags_out; |
699 | } |
700 | if (migrate) { |
701 | if (flags & EXT4_EXTENTS_FL) |
702 | err = ext4_ext_migrate(inode); |
703 | else |
704 | err = ext4_ind_migrate(inode); |
705 | } |
706 | |
707 | flags_out: |
708 | return err; |
709 | } |
710 | |
711 | #ifdef CONFIG_QUOTA |
712 | static int ext4_ioctl_setproject(struct inode *inode, __u32 projid) |
713 | { |
714 | struct super_block *sb = inode->i_sb; |
715 | struct ext4_inode_info *ei = EXT4_I(inode); |
716 | int err, rc; |
717 | handle_t *handle; |
718 | kprojid_t kprojid; |
719 | struct ext4_iloc iloc; |
720 | struct ext4_inode *raw_inode; |
721 | struct dquot *transfer_to[MAXQUOTAS] = { }; |
722 | |
723 | if (!ext4_has_feature_project(sb)) { |
724 | if (projid != EXT4_DEF_PROJID) |
725 | return -EOPNOTSUPP; |
726 | else |
727 | return 0; |
728 | } |
729 | |
730 | if (EXT4_INODE_SIZE(sb) <= EXT4_GOOD_OLD_INODE_SIZE) |
731 | return -EOPNOTSUPP; |
732 | |
733 | kprojid = make_kprojid(from: &init_user_ns, projid: (projid_t)projid); |
734 | |
735 | if (projid_eq(left: kprojid, EXT4_I(inode)->i_projid)) |
736 | return 0; |
737 | |
738 | err = -EPERM; |
739 | /* Is it quota file? Do not allow user to mess with it */ |
740 | if (ext4_is_quota_file(inode)) |
741 | return err; |
742 | |
743 | err = dquot_initialize(inode); |
744 | if (err) |
745 | return err; |
746 | |
747 | err = ext4_get_inode_loc(inode, &iloc); |
748 | if (err) |
749 | return err; |
750 | |
751 | raw_inode = ext4_raw_inode(iloc: &iloc); |
752 | if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) { |
753 | err = ext4_expand_extra_isize(inode, |
754 | new_extra_isize: EXT4_SB(sb)->s_want_extra_isize, |
755 | iloc: &iloc); |
756 | if (err) |
757 | return err; |
758 | } else { |
759 | brelse(bh: iloc.bh); |
760 | } |
761 | |
762 | handle = ext4_journal_start(inode, EXT4_HT_QUOTA, |
763 | EXT4_QUOTA_INIT_BLOCKS(sb) + |
764 | EXT4_QUOTA_DEL_BLOCKS(sb) + 3); |
765 | if (IS_ERR(ptr: handle)) |
766 | return PTR_ERR(ptr: handle); |
767 | |
768 | err = ext4_reserve_inode_write(handle, inode, iloc: &iloc); |
769 | if (err) |
770 | goto out_stop; |
771 | |
772 | transfer_to[PRJQUOTA] = dqget(sb, qid: make_kqid_projid(projid: kprojid)); |
773 | if (!IS_ERR(ptr: transfer_to[PRJQUOTA])) { |
774 | |
775 | /* __dquot_transfer() calls back ext4_get_inode_usage() which |
776 | * counts xattr inode references. |
777 | */ |
778 | down_read(sem: &EXT4_I(inode)->xattr_sem); |
779 | err = __dquot_transfer(inode, transfer_to); |
780 | up_read(sem: &EXT4_I(inode)->xattr_sem); |
781 | dqput(dquot: transfer_to[PRJQUOTA]); |
782 | if (err) |
783 | goto out_dirty; |
784 | } |
785 | |
786 | EXT4_I(inode)->i_projid = kprojid; |
787 | inode_set_ctime_current(inode); |
788 | inode_inc_iversion(inode); |
789 | out_dirty: |
790 | rc = ext4_mark_iloc_dirty(handle, inode, iloc: &iloc); |
791 | if (!err) |
792 | err = rc; |
793 | out_stop: |
794 | ext4_journal_stop(handle); |
795 | return err; |
796 | } |
797 | #else |
798 | static int ext4_ioctl_setproject(struct inode *inode, __u32 projid) |
799 | { |
800 | if (projid != EXT4_DEF_PROJID) |
801 | return -EOPNOTSUPP; |
802 | return 0; |
803 | } |
804 | #endif |
805 | |
806 | int ext4_force_shutdown(struct super_block *sb, u32 flags) |
807 | { |
808 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
809 | int ret; |
810 | |
811 | if (flags > EXT4_GOING_FLAGS_NOLOGFLUSH) |
812 | return -EINVAL; |
813 | |
814 | if (ext4_forced_shutdown(sb)) |
815 | return 0; |
816 | |
817 | ext4_msg(sb, KERN_ALERT, "shut down requested (%d)" , flags); |
818 | trace_ext4_shutdown(sb, flags); |
819 | |
820 | switch (flags) { |
821 | case EXT4_GOING_FLAGS_DEFAULT: |
822 | ret = bdev_freeze(bdev: sb->s_bdev); |
823 | if (ret) |
824 | return ret; |
825 | set_bit(EXT4_FLAGS_SHUTDOWN, addr: &sbi->s_ext4_flags); |
826 | bdev_thaw(bdev: sb->s_bdev); |
827 | break; |
828 | case EXT4_GOING_FLAGS_LOGFLUSH: |
829 | set_bit(EXT4_FLAGS_SHUTDOWN, addr: &sbi->s_ext4_flags); |
830 | if (sbi->s_journal && !is_journal_aborted(journal: sbi->s_journal)) { |
831 | (void) ext4_force_commit(sb); |
832 | jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN); |
833 | } |
834 | break; |
835 | case EXT4_GOING_FLAGS_NOLOGFLUSH: |
836 | set_bit(EXT4_FLAGS_SHUTDOWN, addr: &sbi->s_ext4_flags); |
837 | if (sbi->s_journal && !is_journal_aborted(journal: sbi->s_journal)) |
838 | jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN); |
839 | break; |
840 | default: |
841 | return -EINVAL; |
842 | } |
843 | clear_opt(sb, DISCARD); |
844 | return 0; |
845 | } |
846 | |
847 | static int ext4_ioctl_shutdown(struct super_block *sb, unsigned long arg) |
848 | { |
849 | u32 flags; |
850 | |
851 | if (!capable(CAP_SYS_ADMIN)) |
852 | return -EPERM; |
853 | |
854 | if (get_user(flags, (__u32 __user *)arg)) |
855 | return -EFAULT; |
856 | |
857 | return ext4_force_shutdown(sb, flags); |
858 | } |
859 | |
860 | struct getfsmap_info { |
861 | struct super_block *gi_sb; |
862 | struct fsmap_head __user *gi_data; |
863 | unsigned int gi_idx; |
864 | __u32 gi_last_flags; |
865 | }; |
866 | |
867 | static int ext4_getfsmap_format(struct ext4_fsmap *xfm, void *priv) |
868 | { |
869 | struct getfsmap_info *info = priv; |
870 | struct fsmap fm; |
871 | |
872 | trace_ext4_getfsmap_mapping(sb: info->gi_sb, fsmap: xfm); |
873 | |
874 | info->gi_last_flags = xfm->fmr_flags; |
875 | ext4_fsmap_from_internal(sb: info->gi_sb, dest: &fm, src: xfm); |
876 | if (copy_to_user(to: &info->gi_data->fmh_recs[info->gi_idx++], from: &fm, |
877 | n: sizeof(struct fsmap))) |
878 | return -EFAULT; |
879 | |
880 | return 0; |
881 | } |
882 | |
883 | static int ext4_ioc_getfsmap(struct super_block *sb, |
884 | struct fsmap_head __user *arg) |
885 | { |
886 | struct getfsmap_info info = { NULL }; |
887 | struct ext4_fsmap_head xhead = {0}; |
888 | struct fsmap_head head; |
889 | bool aborted = false; |
890 | int error; |
891 | |
892 | if (copy_from_user(to: &head, from: arg, n: sizeof(struct fsmap_head))) |
893 | return -EFAULT; |
894 | if (memchr_inv(p: head.fmh_reserved, c: 0, size: sizeof(head.fmh_reserved)) || |
895 | memchr_inv(p: head.fmh_keys[0].fmr_reserved, c: 0, |
896 | size: sizeof(head.fmh_keys[0].fmr_reserved)) || |
897 | memchr_inv(p: head.fmh_keys[1].fmr_reserved, c: 0, |
898 | size: sizeof(head.fmh_keys[1].fmr_reserved))) |
899 | return -EINVAL; |
900 | /* |
901 | * ext4 doesn't report file extents at all, so the only valid |
902 | * file offsets are the magic ones (all zeroes or all ones). |
903 | */ |
904 | if (head.fmh_keys[0].fmr_offset || |
905 | (head.fmh_keys[1].fmr_offset != 0 && |
906 | head.fmh_keys[1].fmr_offset != -1ULL)) |
907 | return -EINVAL; |
908 | |
909 | xhead.fmh_iflags = head.fmh_iflags; |
910 | xhead.fmh_count = head.fmh_count; |
911 | ext4_fsmap_to_internal(sb, dest: &xhead.fmh_keys[0], src: &head.fmh_keys[0]); |
912 | ext4_fsmap_to_internal(sb, dest: &xhead.fmh_keys[1], src: &head.fmh_keys[1]); |
913 | |
914 | trace_ext4_getfsmap_low_key(sb, fsmap: &xhead.fmh_keys[0]); |
915 | trace_ext4_getfsmap_high_key(sb, fsmap: &xhead.fmh_keys[1]); |
916 | |
917 | info.gi_sb = sb; |
918 | info.gi_data = arg; |
919 | error = ext4_getfsmap(sb, head: &xhead, formatter: ext4_getfsmap_format, arg: &info); |
920 | if (error == EXT4_QUERY_RANGE_ABORT) |
921 | aborted = true; |
922 | else if (error) |
923 | return error; |
924 | |
925 | /* If we didn't abort, set the "last" flag in the last fmx */ |
926 | if (!aborted && info.gi_idx) { |
927 | info.gi_last_flags |= FMR_OF_LAST; |
928 | if (copy_to_user(to: &info.gi_data->fmh_recs[info.gi_idx - 1].fmr_flags, |
929 | from: &info.gi_last_flags, |
930 | n: sizeof(info.gi_last_flags))) |
931 | return -EFAULT; |
932 | } |
933 | |
934 | /* copy back header */ |
935 | head.fmh_entries = xhead.fmh_entries; |
936 | head.fmh_oflags = xhead.fmh_oflags; |
937 | if (copy_to_user(to: arg, from: &head, n: sizeof(struct fsmap_head))) |
938 | return -EFAULT; |
939 | |
940 | return 0; |
941 | } |
942 | |
943 | static long ext4_ioctl_group_add(struct file *file, |
944 | struct ext4_new_group_data *input) |
945 | { |
946 | struct super_block *sb = file_inode(f: file)->i_sb; |
947 | int err, err2=0; |
948 | |
949 | err = ext4_resize_begin(sb); |
950 | if (err) |
951 | return err; |
952 | |
953 | if (ext4_has_feature_bigalloc(sb)) { |
954 | ext4_msg(sb, KERN_ERR, |
955 | "Online resizing not supported with bigalloc" ); |
956 | err = -EOPNOTSUPP; |
957 | goto group_add_out; |
958 | } |
959 | |
960 | err = mnt_want_write_file(file); |
961 | if (err) |
962 | goto group_add_out; |
963 | |
964 | err = ext4_group_add(sb, input); |
965 | if (EXT4_SB(sb)->s_journal) { |
966 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
967 | err2 = jbd2_journal_flush(journal: EXT4_SB(sb)->s_journal, flags: 0); |
968 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
969 | } |
970 | if (err == 0) |
971 | err = err2; |
972 | mnt_drop_write_file(file); |
973 | if (!err && ext4_has_group_desc_csum(sb) && |
974 | test_opt(sb, INIT_INODE_TABLE)) |
975 | err = ext4_register_li_request(sb, first_not_zeroed: input->group); |
976 | group_add_out: |
977 | err2 = ext4_resize_end(sb, update_backups: false); |
978 | if (err == 0) |
979 | err = err2; |
980 | return err; |
981 | } |
982 | |
983 | int ext4_fileattr_get(struct dentry *dentry, struct fileattr *fa) |
984 | { |
985 | struct inode *inode = d_inode(dentry); |
986 | struct ext4_inode_info *ei = EXT4_I(inode); |
987 | u32 flags = ei->i_flags & EXT4_FL_USER_VISIBLE; |
988 | |
989 | if (S_ISREG(inode->i_mode)) |
990 | flags &= ~FS_PROJINHERIT_FL; |
991 | |
992 | fileattr_fill_flags(fa, flags); |
993 | if (ext4_has_feature_project(sb: inode->i_sb)) |
994 | fa->fsx_projid = from_kprojid(to: &init_user_ns, projid: ei->i_projid); |
995 | |
996 | return 0; |
997 | } |
998 | |
999 | int ext4_fileattr_set(struct mnt_idmap *idmap, |
1000 | struct dentry *dentry, struct fileattr *fa) |
1001 | { |
1002 | struct inode *inode = d_inode(dentry); |
1003 | u32 flags = fa->flags; |
1004 | int err = -EOPNOTSUPP; |
1005 | |
1006 | if (flags & ~EXT4_FL_USER_VISIBLE) |
1007 | goto out; |
1008 | |
1009 | /* |
1010 | * chattr(1) grabs flags via GETFLAGS, modifies the result and |
1011 | * passes that to SETFLAGS. So we cannot easily make SETFLAGS |
1012 | * more restrictive than just silently masking off visible but |
1013 | * not settable flags as we always did. |
1014 | */ |
1015 | flags &= EXT4_FL_USER_MODIFIABLE; |
1016 | if (ext4_mask_flags(mode: inode->i_mode, flags) != flags) |
1017 | goto out; |
1018 | err = ext4_ioctl_check_immutable(inode, new_projid: fa->fsx_projid, flags); |
1019 | if (err) |
1020 | goto out; |
1021 | err = ext4_ioctl_setflags(inode, flags); |
1022 | if (err) |
1023 | goto out; |
1024 | err = ext4_ioctl_setproject(inode, projid: fa->fsx_projid); |
1025 | out: |
1026 | return err; |
1027 | } |
1028 | |
1029 | /* So that the fiemap access checks can't overflow on 32 bit machines. */ |
1030 | #define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent)) |
1031 | |
1032 | static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg) |
1033 | { |
1034 | struct fiemap fiemap; |
1035 | struct fiemap __user *ufiemap = (struct fiemap __user *) arg; |
1036 | struct fiemap_extent_info fieinfo = { 0, }; |
1037 | struct inode *inode = file_inode(f: filp); |
1038 | int error; |
1039 | |
1040 | if (copy_from_user(to: &fiemap, from: ufiemap, n: sizeof(fiemap))) |
1041 | return -EFAULT; |
1042 | |
1043 | if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS) |
1044 | return -EINVAL; |
1045 | |
1046 | fieinfo.fi_flags = fiemap.fm_flags; |
1047 | fieinfo.fi_extents_max = fiemap.fm_extent_count; |
1048 | fieinfo.fi_extents_start = ufiemap->fm_extents; |
1049 | |
1050 | error = ext4_get_es_cache(inode, fieinfo: &fieinfo, start: fiemap.fm_start, |
1051 | len: fiemap.fm_length); |
1052 | fiemap.fm_flags = fieinfo.fi_flags; |
1053 | fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped; |
1054 | if (copy_to_user(to: ufiemap, from: &fiemap, n: sizeof(fiemap))) |
1055 | error = -EFAULT; |
1056 | |
1057 | return error; |
1058 | } |
1059 | |
1060 | static int ext4_ioctl_checkpoint(struct file *filp, unsigned long arg) |
1061 | { |
1062 | int err = 0; |
1063 | __u32 flags = 0; |
1064 | unsigned int flush_flags = 0; |
1065 | struct super_block *sb = file_inode(f: filp)->i_sb; |
1066 | |
1067 | if (copy_from_user(to: &flags, from: (__u32 __user *)arg, |
1068 | n: sizeof(__u32))) |
1069 | return -EFAULT; |
1070 | |
1071 | if (!capable(CAP_SYS_ADMIN)) |
1072 | return -EPERM; |
1073 | |
1074 | /* check for invalid bits set */ |
1075 | if ((flags & ~EXT4_IOC_CHECKPOINT_FLAG_VALID) || |
1076 | ((flags & JBD2_JOURNAL_FLUSH_DISCARD) && |
1077 | (flags & JBD2_JOURNAL_FLUSH_ZEROOUT))) |
1078 | return -EINVAL; |
1079 | |
1080 | if (!EXT4_SB(sb)->s_journal) |
1081 | return -ENODEV; |
1082 | |
1083 | if ((flags & JBD2_JOURNAL_FLUSH_DISCARD) && |
1084 | !bdev_max_discard_sectors(bdev: EXT4_SB(sb)->s_journal->j_dev)) |
1085 | return -EOPNOTSUPP; |
1086 | |
1087 | if (flags & EXT4_IOC_CHECKPOINT_FLAG_DRY_RUN) |
1088 | return 0; |
1089 | |
1090 | if (flags & EXT4_IOC_CHECKPOINT_FLAG_DISCARD) |
1091 | flush_flags |= JBD2_JOURNAL_FLUSH_DISCARD; |
1092 | |
1093 | if (flags & EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT) { |
1094 | flush_flags |= JBD2_JOURNAL_FLUSH_ZEROOUT; |
1095 | pr_info_ratelimited("warning: checkpointing journal with EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT can be slow" ); |
1096 | } |
1097 | |
1098 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
1099 | err = jbd2_journal_flush(journal: EXT4_SB(sb)->s_journal, flags: flush_flags); |
1100 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
1101 | |
1102 | return err; |
1103 | } |
1104 | |
1105 | static int ext4_ioctl_setlabel(struct file *filp, const char __user *user_label) |
1106 | { |
1107 | size_t len; |
1108 | int ret = 0; |
1109 | char new_label[EXT4_LABEL_MAX + 1]; |
1110 | struct super_block *sb = file_inode(f: filp)->i_sb; |
1111 | |
1112 | if (!capable(CAP_SYS_ADMIN)) |
1113 | return -EPERM; |
1114 | |
1115 | /* |
1116 | * Copy the maximum length allowed for ext4 label with one more to |
1117 | * find the required terminating null byte in order to test the |
1118 | * label length. The on disk label doesn't need to be null terminated. |
1119 | */ |
1120 | if (copy_from_user(to: new_label, from: user_label, EXT4_LABEL_MAX + 1)) |
1121 | return -EFAULT; |
1122 | |
1123 | len = strnlen(p: new_label, EXT4_LABEL_MAX + 1); |
1124 | if (len > EXT4_LABEL_MAX) |
1125 | return -EINVAL; |
1126 | |
1127 | /* |
1128 | * Clear the buffer after the new label |
1129 | */ |
1130 | memset(new_label + len, 0, EXT4_LABEL_MAX - len); |
1131 | |
1132 | ret = mnt_want_write_file(file: filp); |
1133 | if (ret) |
1134 | return ret; |
1135 | |
1136 | ret = ext4_update_superblocks_fn(sb, func: ext4_sb_setlabel, arg: new_label); |
1137 | |
1138 | mnt_drop_write_file(file: filp); |
1139 | return ret; |
1140 | } |
1141 | |
1142 | static int ext4_ioctl_getlabel(struct ext4_sb_info *sbi, char __user *user_label) |
1143 | { |
1144 | char label[EXT4_LABEL_MAX + 1]; |
1145 | |
1146 | /* |
1147 | * EXT4_LABEL_MAX must always be smaller than FSLABEL_MAX because |
1148 | * FSLABEL_MAX must include terminating null byte, while s_volume_name |
1149 | * does not have to. |
1150 | */ |
1151 | BUILD_BUG_ON(EXT4_LABEL_MAX >= FSLABEL_MAX); |
1152 | |
1153 | memset(label, 0, sizeof(label)); |
1154 | lock_buffer(bh: sbi->s_sbh); |
1155 | strncpy(p: label, q: sbi->s_es->s_volume_name, EXT4_LABEL_MAX); |
1156 | unlock_buffer(bh: sbi->s_sbh); |
1157 | |
1158 | if (copy_to_user(to: user_label, from: label, n: sizeof(label))) |
1159 | return -EFAULT; |
1160 | return 0; |
1161 | } |
1162 | |
1163 | static int ext4_ioctl_getuuid(struct ext4_sb_info *sbi, |
1164 | struct fsuuid __user *ufsuuid) |
1165 | { |
1166 | struct fsuuid fsuuid; |
1167 | __u8 uuid[UUID_SIZE]; |
1168 | |
1169 | if (copy_from_user(to: &fsuuid, from: ufsuuid, n: sizeof(fsuuid))) |
1170 | return -EFAULT; |
1171 | |
1172 | if (fsuuid.fsu_len == 0) { |
1173 | fsuuid.fsu_len = UUID_SIZE; |
1174 | if (copy_to_user(to: &ufsuuid->fsu_len, from: &fsuuid.fsu_len, |
1175 | n: sizeof(fsuuid.fsu_len))) |
1176 | return -EFAULT; |
1177 | return 0; |
1178 | } |
1179 | |
1180 | if (fsuuid.fsu_len < UUID_SIZE || fsuuid.fsu_flags != 0) |
1181 | return -EINVAL; |
1182 | |
1183 | lock_buffer(bh: sbi->s_sbh); |
1184 | memcpy(uuid, sbi->s_es->s_uuid, UUID_SIZE); |
1185 | unlock_buffer(bh: sbi->s_sbh); |
1186 | |
1187 | fsuuid.fsu_len = UUID_SIZE; |
1188 | if (copy_to_user(to: ufsuuid, from: &fsuuid, n: sizeof(fsuuid)) || |
1189 | copy_to_user(to: &ufsuuid->fsu_uuid[0], from: uuid, UUID_SIZE)) |
1190 | return -EFAULT; |
1191 | return 0; |
1192 | } |
1193 | |
1194 | static int ext4_ioctl_setuuid(struct file *filp, |
1195 | const struct fsuuid __user *ufsuuid) |
1196 | { |
1197 | int ret = 0; |
1198 | struct super_block *sb = file_inode(f: filp)->i_sb; |
1199 | struct fsuuid fsuuid; |
1200 | __u8 uuid[UUID_SIZE]; |
1201 | |
1202 | if (!capable(CAP_SYS_ADMIN)) |
1203 | return -EPERM; |
1204 | |
1205 | /* |
1206 | * If any checksums (group descriptors or metadata) are being used |
1207 | * then the checksum seed feature is required to change the UUID. |
1208 | */ |
1209 | if (((ext4_has_feature_gdt_csum(sb) || ext4_has_metadata_csum(sb)) |
1210 | && !ext4_has_feature_csum_seed(sb)) |
1211 | || ext4_has_feature_stable_inodes(sb)) |
1212 | return -EOPNOTSUPP; |
1213 | |
1214 | if (copy_from_user(to: &fsuuid, from: ufsuuid, n: sizeof(fsuuid))) |
1215 | return -EFAULT; |
1216 | |
1217 | if (fsuuid.fsu_len != UUID_SIZE || fsuuid.fsu_flags != 0) |
1218 | return -EINVAL; |
1219 | |
1220 | if (copy_from_user(to: uuid, from: &ufsuuid->fsu_uuid[0], UUID_SIZE)) |
1221 | return -EFAULT; |
1222 | |
1223 | ret = mnt_want_write_file(file: filp); |
1224 | if (ret) |
1225 | return ret; |
1226 | |
1227 | ret = ext4_update_superblocks_fn(sb, func: ext4_sb_setuuid, arg: &uuid); |
1228 | mnt_drop_write_file(file: filp); |
1229 | |
1230 | return ret; |
1231 | } |
1232 | |
1233 | static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1234 | { |
1235 | struct inode *inode = file_inode(f: filp); |
1236 | struct super_block *sb = inode->i_sb; |
1237 | struct mnt_idmap *idmap = file_mnt_idmap(file: filp); |
1238 | |
1239 | ext4_debug("cmd = %u, arg = %lu\n" , cmd, arg); |
1240 | |
1241 | switch (cmd) { |
1242 | case FS_IOC_GETFSMAP: |
1243 | return ext4_ioc_getfsmap(sb, arg: (void __user *)arg); |
1244 | case EXT4_IOC_GETVERSION: |
1245 | case EXT4_IOC_GETVERSION_OLD: |
1246 | return put_user(inode->i_generation, (int __user *) arg); |
1247 | case EXT4_IOC_SETVERSION: |
1248 | case EXT4_IOC_SETVERSION_OLD: { |
1249 | handle_t *handle; |
1250 | struct ext4_iloc iloc; |
1251 | __u32 generation; |
1252 | int err; |
1253 | |
1254 | if (!inode_owner_or_capable(idmap, inode)) |
1255 | return -EPERM; |
1256 | |
1257 | if (ext4_has_metadata_csum(sb: inode->i_sb)) { |
1258 | ext4_warning(sb, "Setting inode version is not " |
1259 | "supported with metadata_csum enabled." ); |
1260 | return -ENOTTY; |
1261 | } |
1262 | |
1263 | err = mnt_want_write_file(file: filp); |
1264 | if (err) |
1265 | return err; |
1266 | if (get_user(generation, (int __user *) arg)) { |
1267 | err = -EFAULT; |
1268 | goto setversion_out; |
1269 | } |
1270 | |
1271 | inode_lock(inode); |
1272 | handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); |
1273 | if (IS_ERR(ptr: handle)) { |
1274 | err = PTR_ERR(ptr: handle); |
1275 | goto unlock_out; |
1276 | } |
1277 | err = ext4_reserve_inode_write(handle, inode, iloc: &iloc); |
1278 | if (err == 0) { |
1279 | inode_set_ctime_current(inode); |
1280 | inode_inc_iversion(inode); |
1281 | inode->i_generation = generation; |
1282 | err = ext4_mark_iloc_dirty(handle, inode, iloc: &iloc); |
1283 | } |
1284 | ext4_journal_stop(handle); |
1285 | |
1286 | unlock_out: |
1287 | inode_unlock(inode); |
1288 | setversion_out: |
1289 | mnt_drop_write_file(file: filp); |
1290 | return err; |
1291 | } |
1292 | case EXT4_IOC_GROUP_EXTEND: { |
1293 | ext4_fsblk_t n_blocks_count; |
1294 | int err, err2=0; |
1295 | |
1296 | err = ext4_resize_begin(sb); |
1297 | if (err) |
1298 | return err; |
1299 | |
1300 | if (get_user(n_blocks_count, (__u32 __user *)arg)) { |
1301 | err = -EFAULT; |
1302 | goto group_extend_out; |
1303 | } |
1304 | |
1305 | if (ext4_has_feature_bigalloc(sb)) { |
1306 | ext4_msg(sb, KERN_ERR, |
1307 | "Online resizing not supported with bigalloc" ); |
1308 | err = -EOPNOTSUPP; |
1309 | goto group_extend_out; |
1310 | } |
1311 | |
1312 | err = mnt_want_write_file(file: filp); |
1313 | if (err) |
1314 | goto group_extend_out; |
1315 | |
1316 | err = ext4_group_extend(sb, es: EXT4_SB(sb)->s_es, n_blocks_count); |
1317 | if (EXT4_SB(sb)->s_journal) { |
1318 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
1319 | err2 = jbd2_journal_flush(journal: EXT4_SB(sb)->s_journal, flags: 0); |
1320 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
1321 | } |
1322 | if (err == 0) |
1323 | err = err2; |
1324 | mnt_drop_write_file(file: filp); |
1325 | group_extend_out: |
1326 | err2 = ext4_resize_end(sb, update_backups: false); |
1327 | if (err == 0) |
1328 | err = err2; |
1329 | return err; |
1330 | } |
1331 | |
1332 | case EXT4_IOC_MOVE_EXT: { |
1333 | struct move_extent me; |
1334 | struct fd donor; |
1335 | int err; |
1336 | |
1337 | if (!(filp->f_mode & FMODE_READ) || |
1338 | !(filp->f_mode & FMODE_WRITE)) |
1339 | return -EBADF; |
1340 | |
1341 | if (copy_from_user(to: &me, |
1342 | from: (struct move_extent __user *)arg, n: sizeof(me))) |
1343 | return -EFAULT; |
1344 | me.moved_len = 0; |
1345 | |
1346 | donor = fdget(fd: me.donor_fd); |
1347 | if (!donor.file) |
1348 | return -EBADF; |
1349 | |
1350 | if (!(donor.file->f_mode & FMODE_WRITE)) { |
1351 | err = -EBADF; |
1352 | goto mext_out; |
1353 | } |
1354 | |
1355 | if (ext4_has_feature_bigalloc(sb)) { |
1356 | ext4_msg(sb, KERN_ERR, |
1357 | "Online defrag not supported with bigalloc" ); |
1358 | err = -EOPNOTSUPP; |
1359 | goto mext_out; |
1360 | } else if (IS_DAX(inode)) { |
1361 | ext4_msg(sb, KERN_ERR, |
1362 | "Online defrag not supported with DAX" ); |
1363 | err = -EOPNOTSUPP; |
1364 | goto mext_out; |
1365 | } |
1366 | |
1367 | err = mnt_want_write_file(file: filp); |
1368 | if (err) |
1369 | goto mext_out; |
1370 | |
1371 | err = ext4_move_extents(o_filp: filp, d_filp: donor.file, start_orig: me.orig_start, |
1372 | start_donor: me.donor_start, len: me.len, moved_len: &me.moved_len); |
1373 | mnt_drop_write_file(file: filp); |
1374 | |
1375 | if (copy_to_user(to: (struct move_extent __user *)arg, |
1376 | from: &me, n: sizeof(me))) |
1377 | err = -EFAULT; |
1378 | mext_out: |
1379 | fdput(fd: donor); |
1380 | return err; |
1381 | } |
1382 | |
1383 | case EXT4_IOC_GROUP_ADD: { |
1384 | struct ext4_new_group_data input; |
1385 | |
1386 | if (copy_from_user(to: &input, from: (struct ext4_new_group_input __user *)arg, |
1387 | n: sizeof(input))) |
1388 | return -EFAULT; |
1389 | |
1390 | return ext4_ioctl_group_add(file: filp, input: &input); |
1391 | } |
1392 | |
1393 | case EXT4_IOC_MIGRATE: |
1394 | { |
1395 | int err; |
1396 | if (!inode_owner_or_capable(idmap, inode)) |
1397 | return -EACCES; |
1398 | |
1399 | err = mnt_want_write_file(file: filp); |
1400 | if (err) |
1401 | return err; |
1402 | /* |
1403 | * inode_mutex prevent write and truncate on the file. |
1404 | * Read still goes through. We take i_data_sem in |
1405 | * ext4_ext_swap_inode_data before we switch the |
1406 | * inode format to prevent read. |
1407 | */ |
1408 | inode_lock((inode)); |
1409 | err = ext4_ext_migrate(inode); |
1410 | inode_unlock((inode)); |
1411 | mnt_drop_write_file(file: filp); |
1412 | return err; |
1413 | } |
1414 | |
1415 | case EXT4_IOC_ALLOC_DA_BLKS: |
1416 | { |
1417 | int err; |
1418 | if (!inode_owner_or_capable(idmap, inode)) |
1419 | return -EACCES; |
1420 | |
1421 | err = mnt_want_write_file(file: filp); |
1422 | if (err) |
1423 | return err; |
1424 | err = ext4_alloc_da_blocks(inode); |
1425 | mnt_drop_write_file(file: filp); |
1426 | return err; |
1427 | } |
1428 | |
1429 | case EXT4_IOC_SWAP_BOOT: |
1430 | { |
1431 | int err; |
1432 | if (!(filp->f_mode & FMODE_WRITE)) |
1433 | return -EBADF; |
1434 | err = mnt_want_write_file(file: filp); |
1435 | if (err) |
1436 | return err; |
1437 | err = swap_inode_boot_loader(sb, idmap, inode); |
1438 | mnt_drop_write_file(file: filp); |
1439 | return err; |
1440 | } |
1441 | |
1442 | case EXT4_IOC_RESIZE_FS: { |
1443 | ext4_fsblk_t n_blocks_count; |
1444 | int err = 0, err2 = 0; |
1445 | ext4_group_t o_group = EXT4_SB(sb)->s_groups_count; |
1446 | |
1447 | if (copy_from_user(to: &n_blocks_count, from: (__u64 __user *)arg, |
1448 | n: sizeof(__u64))) { |
1449 | return -EFAULT; |
1450 | } |
1451 | |
1452 | err = ext4_resize_begin(sb); |
1453 | if (err) |
1454 | return err; |
1455 | |
1456 | err = mnt_want_write_file(file: filp); |
1457 | if (err) |
1458 | goto resizefs_out; |
1459 | |
1460 | err = ext4_resize_fs(sb, n_blocks_count); |
1461 | if (EXT4_SB(sb)->s_journal) { |
1462 | ext4_fc_mark_ineligible(sb, reason: EXT4_FC_REASON_RESIZE, NULL); |
1463 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
1464 | err2 = jbd2_journal_flush(journal: EXT4_SB(sb)->s_journal, flags: 0); |
1465 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
1466 | } |
1467 | if (err == 0) |
1468 | err = err2; |
1469 | mnt_drop_write_file(file: filp); |
1470 | if (!err && (o_group < EXT4_SB(sb)->s_groups_count) && |
1471 | ext4_has_group_desc_csum(sb) && |
1472 | test_opt(sb, INIT_INODE_TABLE)) |
1473 | err = ext4_register_li_request(sb, first_not_zeroed: o_group); |
1474 | |
1475 | resizefs_out: |
1476 | err2 = ext4_resize_end(sb, update_backups: true); |
1477 | if (err == 0) |
1478 | err = err2; |
1479 | return err; |
1480 | } |
1481 | |
1482 | case FITRIM: |
1483 | { |
1484 | struct fstrim_range range; |
1485 | int ret = 0; |
1486 | |
1487 | if (!capable(CAP_SYS_ADMIN)) |
1488 | return -EPERM; |
1489 | |
1490 | if (!bdev_max_discard_sectors(bdev: sb->s_bdev)) |
1491 | return -EOPNOTSUPP; |
1492 | |
1493 | /* |
1494 | * We haven't replayed the journal, so we cannot use our |
1495 | * block-bitmap-guided storage zapping commands. |
1496 | */ |
1497 | if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) |
1498 | return -EROFS; |
1499 | |
1500 | if (copy_from_user(to: &range, from: (struct fstrim_range __user *)arg, |
1501 | n: sizeof(range))) |
1502 | return -EFAULT; |
1503 | |
1504 | ret = ext4_trim_fs(sb, &range); |
1505 | if (ret < 0) |
1506 | return ret; |
1507 | |
1508 | if (copy_to_user(to: (struct fstrim_range __user *)arg, from: &range, |
1509 | n: sizeof(range))) |
1510 | return -EFAULT; |
1511 | |
1512 | return 0; |
1513 | } |
1514 | case EXT4_IOC_PRECACHE_EXTENTS: |
1515 | return ext4_ext_precache(inode); |
1516 | |
1517 | case FS_IOC_SET_ENCRYPTION_POLICY: |
1518 | if (!ext4_has_feature_encrypt(sb)) |
1519 | return -EOPNOTSUPP; |
1520 | return fscrypt_ioctl_set_policy(filp, arg: (const void __user *)arg); |
1521 | |
1522 | case FS_IOC_GET_ENCRYPTION_PWSALT: |
1523 | return ext4_ioctl_get_encryption_pwsalt(filp, arg: (void __user *)arg); |
1524 | |
1525 | case FS_IOC_GET_ENCRYPTION_POLICY: |
1526 | if (!ext4_has_feature_encrypt(sb)) |
1527 | return -EOPNOTSUPP; |
1528 | return fscrypt_ioctl_get_policy(filp, arg: (void __user *)arg); |
1529 | |
1530 | case FS_IOC_GET_ENCRYPTION_POLICY_EX: |
1531 | if (!ext4_has_feature_encrypt(sb)) |
1532 | return -EOPNOTSUPP; |
1533 | return fscrypt_ioctl_get_policy_ex(filp, arg: (void __user *)arg); |
1534 | |
1535 | case FS_IOC_ADD_ENCRYPTION_KEY: |
1536 | if (!ext4_has_feature_encrypt(sb)) |
1537 | return -EOPNOTSUPP; |
1538 | return fscrypt_ioctl_add_key(filp, arg: (void __user *)arg); |
1539 | |
1540 | case FS_IOC_REMOVE_ENCRYPTION_KEY: |
1541 | if (!ext4_has_feature_encrypt(sb)) |
1542 | return -EOPNOTSUPP; |
1543 | return fscrypt_ioctl_remove_key(filp, arg: (void __user *)arg); |
1544 | |
1545 | case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS: |
1546 | if (!ext4_has_feature_encrypt(sb)) |
1547 | return -EOPNOTSUPP; |
1548 | return fscrypt_ioctl_remove_key_all_users(filp, |
1549 | arg: (void __user *)arg); |
1550 | case FS_IOC_GET_ENCRYPTION_KEY_STATUS: |
1551 | if (!ext4_has_feature_encrypt(sb)) |
1552 | return -EOPNOTSUPP; |
1553 | return fscrypt_ioctl_get_key_status(filp, arg: (void __user *)arg); |
1554 | |
1555 | case FS_IOC_GET_ENCRYPTION_NONCE: |
1556 | if (!ext4_has_feature_encrypt(sb)) |
1557 | return -EOPNOTSUPP; |
1558 | return fscrypt_ioctl_get_nonce(filp, arg: (void __user *)arg); |
1559 | |
1560 | case EXT4_IOC_CLEAR_ES_CACHE: |
1561 | { |
1562 | if (!inode_owner_or_capable(idmap, inode)) |
1563 | return -EACCES; |
1564 | ext4_clear_inode_es(inode); |
1565 | return 0; |
1566 | } |
1567 | |
1568 | case EXT4_IOC_GETSTATE: |
1569 | { |
1570 | __u32 state = 0; |
1571 | |
1572 | if (ext4_test_inode_state(inode, bit: EXT4_STATE_EXT_PRECACHED)) |
1573 | state |= EXT4_STATE_FLAG_EXT_PRECACHED; |
1574 | if (ext4_test_inode_state(inode, bit: EXT4_STATE_NEW)) |
1575 | state |= EXT4_STATE_FLAG_NEW; |
1576 | if (ext4_test_inode_state(inode, bit: EXT4_STATE_NEWENTRY)) |
1577 | state |= EXT4_STATE_FLAG_NEWENTRY; |
1578 | if (ext4_test_inode_state(inode, bit: EXT4_STATE_DA_ALLOC_CLOSE)) |
1579 | state |= EXT4_STATE_FLAG_DA_ALLOC_CLOSE; |
1580 | |
1581 | return put_user(state, (__u32 __user *) arg); |
1582 | } |
1583 | |
1584 | case EXT4_IOC_GET_ES_CACHE: |
1585 | return ext4_ioctl_get_es_cache(filp, arg); |
1586 | |
1587 | case EXT4_IOC_SHUTDOWN: |
1588 | return ext4_ioctl_shutdown(sb, arg); |
1589 | |
1590 | case FS_IOC_ENABLE_VERITY: |
1591 | if (!ext4_has_feature_verity(sb)) |
1592 | return -EOPNOTSUPP; |
1593 | return fsverity_ioctl_enable(filp, arg: (const void __user *)arg); |
1594 | |
1595 | case FS_IOC_MEASURE_VERITY: |
1596 | if (!ext4_has_feature_verity(sb)) |
1597 | return -EOPNOTSUPP; |
1598 | return fsverity_ioctl_measure(filp, arg: (void __user *)arg); |
1599 | |
1600 | case FS_IOC_READ_VERITY_METADATA: |
1601 | if (!ext4_has_feature_verity(sb)) |
1602 | return -EOPNOTSUPP; |
1603 | return fsverity_ioctl_read_metadata(filp, |
1604 | uarg: (const void __user *)arg); |
1605 | |
1606 | case EXT4_IOC_CHECKPOINT: |
1607 | return ext4_ioctl_checkpoint(filp, arg); |
1608 | |
1609 | case FS_IOC_GETFSLABEL: |
1610 | return ext4_ioctl_getlabel(sbi: EXT4_SB(sb), user_label: (void __user *)arg); |
1611 | |
1612 | case FS_IOC_SETFSLABEL: |
1613 | return ext4_ioctl_setlabel(filp, |
1614 | user_label: (const void __user *)arg); |
1615 | |
1616 | case EXT4_IOC_GETFSUUID: |
1617 | return ext4_ioctl_getuuid(sbi: EXT4_SB(sb), ufsuuid: (void __user *)arg); |
1618 | case EXT4_IOC_SETFSUUID: |
1619 | return ext4_ioctl_setuuid(filp, ufsuuid: (const void __user *)arg); |
1620 | default: |
1621 | return -ENOTTY; |
1622 | } |
1623 | } |
1624 | |
1625 | long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1626 | { |
1627 | return __ext4_ioctl(filp, cmd, arg); |
1628 | } |
1629 | |
1630 | #ifdef CONFIG_COMPAT |
1631 | long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
1632 | { |
1633 | /* These are just misnamed, they actually get/put from/to user an int */ |
1634 | switch (cmd) { |
1635 | case EXT4_IOC32_GETVERSION: |
1636 | cmd = EXT4_IOC_GETVERSION; |
1637 | break; |
1638 | case EXT4_IOC32_SETVERSION: |
1639 | cmd = EXT4_IOC_SETVERSION; |
1640 | break; |
1641 | case EXT4_IOC32_GROUP_EXTEND: |
1642 | cmd = EXT4_IOC_GROUP_EXTEND; |
1643 | break; |
1644 | case EXT4_IOC32_GETVERSION_OLD: |
1645 | cmd = EXT4_IOC_GETVERSION_OLD; |
1646 | break; |
1647 | case EXT4_IOC32_SETVERSION_OLD: |
1648 | cmd = EXT4_IOC_SETVERSION_OLD; |
1649 | break; |
1650 | case EXT4_IOC32_GETRSVSZ: |
1651 | cmd = EXT4_IOC_GETRSVSZ; |
1652 | break; |
1653 | case EXT4_IOC32_SETRSVSZ: |
1654 | cmd = EXT4_IOC_SETRSVSZ; |
1655 | break; |
1656 | case EXT4_IOC32_GROUP_ADD: { |
1657 | struct compat_ext4_new_group_input __user *uinput; |
1658 | struct ext4_new_group_data input; |
1659 | int err; |
1660 | |
1661 | uinput = compat_ptr(uptr: arg); |
1662 | err = get_user(input.group, &uinput->group); |
1663 | err |= get_user(input.block_bitmap, &uinput->block_bitmap); |
1664 | err |= get_user(input.inode_bitmap, &uinput->inode_bitmap); |
1665 | err |= get_user(input.inode_table, &uinput->inode_table); |
1666 | err |= get_user(input.blocks_count, &uinput->blocks_count); |
1667 | err |= get_user(input.reserved_blocks, |
1668 | &uinput->reserved_blocks); |
1669 | if (err) |
1670 | return -EFAULT; |
1671 | return ext4_ioctl_group_add(file, input: &input); |
1672 | } |
1673 | case EXT4_IOC_MOVE_EXT: |
1674 | case EXT4_IOC_RESIZE_FS: |
1675 | case FITRIM: |
1676 | case EXT4_IOC_PRECACHE_EXTENTS: |
1677 | case FS_IOC_SET_ENCRYPTION_POLICY: |
1678 | case FS_IOC_GET_ENCRYPTION_PWSALT: |
1679 | case FS_IOC_GET_ENCRYPTION_POLICY: |
1680 | case FS_IOC_GET_ENCRYPTION_POLICY_EX: |
1681 | case FS_IOC_ADD_ENCRYPTION_KEY: |
1682 | case FS_IOC_REMOVE_ENCRYPTION_KEY: |
1683 | case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS: |
1684 | case FS_IOC_GET_ENCRYPTION_KEY_STATUS: |
1685 | case FS_IOC_GET_ENCRYPTION_NONCE: |
1686 | case EXT4_IOC_SHUTDOWN: |
1687 | case FS_IOC_GETFSMAP: |
1688 | case FS_IOC_ENABLE_VERITY: |
1689 | case FS_IOC_MEASURE_VERITY: |
1690 | case FS_IOC_READ_VERITY_METADATA: |
1691 | case EXT4_IOC_CLEAR_ES_CACHE: |
1692 | case EXT4_IOC_GETSTATE: |
1693 | case EXT4_IOC_GET_ES_CACHE: |
1694 | case EXT4_IOC_CHECKPOINT: |
1695 | case FS_IOC_GETFSLABEL: |
1696 | case FS_IOC_SETFSLABEL: |
1697 | case EXT4_IOC_GETFSUUID: |
1698 | case EXT4_IOC_SETFSUUID: |
1699 | break; |
1700 | default: |
1701 | return -ENOIOCTLCMD; |
1702 | } |
1703 | return ext4_ioctl(filp: file, cmd, arg: (unsigned long) compat_ptr(uptr: arg)); |
1704 | } |
1705 | #endif |
1706 | |
1707 | static void set_overhead(struct ext4_super_block *es, const void *arg) |
1708 | { |
1709 | es->s_overhead_clusters = cpu_to_le32(*((unsigned long *) arg)); |
1710 | } |
1711 | |
1712 | int ext4_update_overhead(struct super_block *sb, bool force) |
1713 | { |
1714 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1715 | |
1716 | if (sb_rdonly(sb)) |
1717 | return 0; |
1718 | if (!force && |
1719 | (sbi->s_overhead == 0 || |
1720 | sbi->s_overhead == le32_to_cpu(sbi->s_es->s_overhead_clusters))) |
1721 | return 0; |
1722 | return ext4_update_superblocks_fn(sb, func: set_overhead, arg: &sbi->s_overhead); |
1723 | } |
1724 | |