1 /* 2 * linux/fs/ext4/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/fs.h> 11 #include <linux/jbd2.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 <asm/uaccess.h> 18 #include "ext4_jbd2.h" 19 #include "ext4.h" 20 #include "ext4_extents.h" 21 22 #define MAX_32_NUM ((((unsigned long long) 1) << 32) - 1) 23 24 /** 25 * Swap memory between @a and @b for @len bytes. 26 * 27 * @a: pointer to first memory area 28 * @b: pointer to second memory area 29 * @len: number of bytes to swap 30 * 31 */ 32 static void memswap(void *a, void *b, size_t len) 33 { 34 unsigned char *ap, *bp; 35 unsigned char tmp; 36 37 ap = (unsigned char *)a; 38 bp = (unsigned char *)b; 39 while (len-- > 0) { 40 tmp = *ap; 41 *ap = *bp; 42 *bp = tmp; 43 ap++; 44 bp++; 45 } 46 } 47 48 /** 49 * Swap i_data and associated attributes between @inode1 and @inode2. 50 * This function is used for the primary swap between inode1 and inode2 51 * and also to revert this primary swap in case of errors. 52 * 53 * Therefore you have to make sure, that calling this method twice 54 * will revert all changes. 55 * 56 * @inode1: pointer to first inode 57 * @inode2: pointer to second inode 58 */ 59 static void swap_inode_data(struct inode *inode1, struct inode *inode2) 60 { 61 loff_t isize; 62 struct ext4_inode_info *ei1; 63 struct ext4_inode_info *ei2; 64 65 ei1 = EXT4_I(inode1); 66 ei2 = EXT4_I(inode2); 67 68 memswap(&inode1->i_flags, &inode2->i_flags, sizeof(inode1->i_flags)); 69 memswap(&inode1->i_version, &inode2->i_version, 70 sizeof(inode1->i_version)); 71 memswap(&inode1->i_blocks, &inode2->i_blocks, 72 sizeof(inode1->i_blocks)); 73 memswap(&inode1->i_bytes, &inode2->i_bytes, sizeof(inode1->i_bytes)); 74 memswap(&inode1->i_atime, &inode2->i_atime, sizeof(inode1->i_atime)); 75 memswap(&inode1->i_mtime, &inode2->i_mtime, sizeof(inode1->i_mtime)); 76 77 memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data)); 78 memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags)); 79 memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize)); 80 ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS); 81 ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS); 82 ext4_es_lru_del(inode1); 83 ext4_es_lru_del(inode2); 84 85 isize = i_size_read(inode1); 86 i_size_write(inode1, i_size_read(inode2)); 87 i_size_write(inode2, isize); 88 } 89 90 /** 91 * Swap the information from the given @inode and the inode 92 * EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other 93 * important fields of the inodes. 94 * 95 * @sb: the super block of the filesystem 96 * @inode: the inode to swap with EXT4_BOOT_LOADER_INO 97 * 98 */ 99 static long swap_inode_boot_loader(struct super_block *sb, 100 struct inode *inode) 101 { 102 handle_t *handle; 103 int err; 104 struct inode *inode_bl; 105 struct ext4_inode_info *ei; 106 struct ext4_inode_info *ei_bl; 107 struct ext4_sb_info *sbi; 108 109 if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode)) { 110 err = -EINVAL; 111 goto swap_boot_out; 112 } 113 114 if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) { 115 err = -EPERM; 116 goto swap_boot_out; 117 } 118 119 sbi = EXT4_SB(sb); 120 ei = EXT4_I(inode); 121 122 inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO); 123 if (IS_ERR(inode_bl)) { 124 err = PTR_ERR(inode_bl); 125 goto swap_boot_out; 126 } 127 ei_bl = EXT4_I(inode_bl); 128 129 filemap_flush(inode->i_mapping); 130 filemap_flush(inode_bl->i_mapping); 131 132 /* Protect orig inodes against a truncate and make sure, 133 * that only 1 swap_inode_boot_loader is running. */ 134 ext4_inode_double_lock(inode, inode_bl); 135 136 truncate_inode_pages(&inode->i_data, 0); 137 truncate_inode_pages(&inode_bl->i_data, 0); 138 139 /* Wait for all existing dio workers */ 140 ext4_inode_block_unlocked_dio(inode); 141 ext4_inode_block_unlocked_dio(inode_bl); 142 inode_dio_wait(inode); 143 inode_dio_wait(inode_bl); 144 145 handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2); 146 if (IS_ERR(handle)) { 147 err = -EINVAL; 148 goto swap_boot_out; 149 } 150 151 /* Protect extent tree against block allocations via delalloc */ 152 ext4_double_down_write_data_sem(inode, inode_bl); 153 154 if (inode_bl->i_nlink == 0) { 155 /* this inode has never been used as a BOOT_LOADER */ 156 set_nlink(inode_bl, 1); 157 i_uid_write(inode_bl, 0); 158 i_gid_write(inode_bl, 0); 159 inode_bl->i_flags = 0; 160 ei_bl->i_flags = 0; 161 inode_bl->i_version = 1; 162 i_size_write(inode_bl, 0); 163 inode_bl->i_mode = S_IFREG; 164 if (EXT4_HAS_INCOMPAT_FEATURE(sb, 165 EXT4_FEATURE_INCOMPAT_EXTENTS)) { 166 ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS); 167 ext4_ext_tree_init(handle, inode_bl); 168 } else 169 memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data)); 170 } 171 172 swap_inode_data(inode, inode_bl); 173 174 inode->i_ctime = inode_bl->i_ctime = ext4_current_time(inode); 175 176 spin_lock(&sbi->s_next_gen_lock); 177 inode->i_generation = sbi->s_next_generation++; 178 inode_bl->i_generation = sbi->s_next_generation++; 179 spin_unlock(&sbi->s_next_gen_lock); 180 181 ext4_discard_preallocations(inode); 182 183 err = ext4_mark_inode_dirty(handle, inode); 184 if (err < 0) { 185 ext4_warning(inode->i_sb, 186 "couldn't mark inode #%lu dirty (err %d)", 187 inode->i_ino, err); 188 /* Revert all changes: */ 189 swap_inode_data(inode, inode_bl); 190 } else { 191 err = ext4_mark_inode_dirty(handle, inode_bl); 192 if (err < 0) { 193 ext4_warning(inode_bl->i_sb, 194 "couldn't mark inode #%lu dirty (err %d)", 195 inode_bl->i_ino, err); 196 /* Revert all changes: */ 197 swap_inode_data(inode, inode_bl); 198 ext4_mark_inode_dirty(handle, inode); 199 } 200 } 201 202 ext4_journal_stop(handle); 203 204 ext4_double_up_write_data_sem(inode, inode_bl); 205 206 ext4_inode_resume_unlocked_dio(inode); 207 ext4_inode_resume_unlocked_dio(inode_bl); 208 209 ext4_inode_double_unlock(inode, inode_bl); 210 211 iput(inode_bl); 212 213 swap_boot_out: 214 return err; 215 } 216 217 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 218 { 219 struct inode *inode = file_inode(filp); 220 struct super_block *sb = inode->i_sb; 221 struct ext4_inode_info *ei = EXT4_I(inode); 222 unsigned int flags; 223 224 ext4_debug("cmd = %u, arg = %lu\n", cmd, arg); 225 226 switch (cmd) { 227 case EXT4_IOC_GETFLAGS: 228 ext4_get_inode_flags(ei); 229 flags = ei->i_flags & EXT4_FL_USER_VISIBLE; 230 return put_user(flags, (int __user *) arg); 231 case EXT4_IOC_SETFLAGS: { 232 handle_t *handle = NULL; 233 int err, migrate = 0; 234 struct ext4_iloc iloc; 235 unsigned int oldflags, mask, i; 236 unsigned int jflag; 237 238 if (!inode_owner_or_capable(inode)) 239 return -EACCES; 240 241 if (get_user(flags, (int __user *) arg)) 242 return -EFAULT; 243 244 err = mnt_want_write_file(filp); 245 if (err) 246 return err; 247 248 flags = ext4_mask_flags(inode->i_mode, flags); 249 250 err = -EPERM; 251 mutex_lock(&inode->i_mutex); 252 /* Is it quota file? Do not allow user to mess with it */ 253 if (IS_NOQUOTA(inode)) 254 goto flags_out; 255 256 oldflags = ei->i_flags; 257 258 /* The JOURNAL_DATA flag is modifiable only by root */ 259 jflag = flags & EXT4_JOURNAL_DATA_FL; 260 261 /* 262 * The IMMUTABLE and APPEND_ONLY flags can only be changed by 263 * the relevant capability. 264 * 265 * This test looks nicer. Thanks to Pauline Middelink 266 */ 267 if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { 268 if (!capable(CAP_LINUX_IMMUTABLE)) 269 goto flags_out; 270 } 271 272 /* 273 * The JOURNAL_DATA flag can only be changed by 274 * the relevant capability. 275 */ 276 if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { 277 if (!capable(CAP_SYS_RESOURCE)) 278 goto flags_out; 279 } 280 if ((flags ^ oldflags) & EXT4_EXTENTS_FL) 281 migrate = 1; 282 283 if (flags & EXT4_EOFBLOCKS_FL) { 284 /* we don't support adding EOFBLOCKS flag */ 285 if (!(oldflags & EXT4_EOFBLOCKS_FL)) { 286 err = -EOPNOTSUPP; 287 goto flags_out; 288 } 289 } else if (oldflags & EXT4_EOFBLOCKS_FL) 290 ext4_truncate(inode); 291 292 handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); 293 if (IS_ERR(handle)) { 294 err = PTR_ERR(handle); 295 goto flags_out; 296 } 297 if (IS_SYNC(inode)) 298 ext4_handle_sync(handle); 299 err = ext4_reserve_inode_write(handle, inode, &iloc); 300 if (err) 301 goto flags_err; 302 303 for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { 304 if (!(mask & EXT4_FL_USER_MODIFIABLE)) 305 continue; 306 if (mask & flags) 307 ext4_set_inode_flag(inode, i); 308 else 309 ext4_clear_inode_flag(inode, i); 310 } 311 312 ext4_set_inode_flags(inode); 313 inode->i_ctime = ext4_current_time(inode); 314 315 err = ext4_mark_iloc_dirty(handle, inode, &iloc); 316 flags_err: 317 ext4_journal_stop(handle); 318 if (err) 319 goto flags_out; 320 321 if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) 322 err = ext4_change_inode_journal_flag(inode, jflag); 323 if (err) 324 goto flags_out; 325 if (migrate) { 326 if (flags & EXT4_EXTENTS_FL) 327 err = ext4_ext_migrate(inode); 328 else 329 err = ext4_ind_migrate(inode); 330 } 331 332 flags_out: 333 mutex_unlock(&inode->i_mutex); 334 mnt_drop_write_file(filp); 335 return err; 336 } 337 case EXT4_IOC_GETVERSION: 338 case EXT4_IOC_GETVERSION_OLD: 339 return put_user(inode->i_generation, (int __user *) arg); 340 case EXT4_IOC_SETVERSION: 341 case EXT4_IOC_SETVERSION_OLD: { 342 handle_t *handle; 343 struct ext4_iloc iloc; 344 __u32 generation; 345 int err; 346 347 if (!inode_owner_or_capable(inode)) 348 return -EPERM; 349 350 if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 351 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { 352 ext4_warning(sb, "Setting inode version is not " 353 "supported with metadata_csum enabled."); 354 return -ENOTTY; 355 } 356 357 err = mnt_want_write_file(filp); 358 if (err) 359 return err; 360 if (get_user(generation, (int __user *) arg)) { 361 err = -EFAULT; 362 goto setversion_out; 363 } 364 365 mutex_lock(&inode->i_mutex); 366 handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); 367 if (IS_ERR(handle)) { 368 err = PTR_ERR(handle); 369 goto unlock_out; 370 } 371 err = ext4_reserve_inode_write(handle, inode, &iloc); 372 if (err == 0) { 373 inode->i_ctime = ext4_current_time(inode); 374 inode->i_generation = generation; 375 err = ext4_mark_iloc_dirty(handle, inode, &iloc); 376 } 377 ext4_journal_stop(handle); 378 379 unlock_out: 380 mutex_unlock(&inode->i_mutex); 381 setversion_out: 382 mnt_drop_write_file(filp); 383 return err; 384 } 385 case EXT4_IOC_GROUP_EXTEND: { 386 ext4_fsblk_t n_blocks_count; 387 int err, err2=0; 388 389 err = ext4_resize_begin(sb); 390 if (err) 391 return err; 392 393 if (get_user(n_blocks_count, (__u32 __user *)arg)) { 394 err = -EFAULT; 395 goto group_extend_out; 396 } 397 398 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 399 EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 400 ext4_msg(sb, KERN_ERR, 401 "Online resizing not supported with bigalloc"); 402 err = -EOPNOTSUPP; 403 goto group_extend_out; 404 } 405 406 err = mnt_want_write_file(filp); 407 if (err) 408 goto group_extend_out; 409 410 err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); 411 if (EXT4_SB(sb)->s_journal) { 412 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 413 err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 414 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 415 } 416 if (err == 0) 417 err = err2; 418 mnt_drop_write_file(filp); 419 group_extend_out: 420 ext4_resize_end(sb); 421 return err; 422 } 423 424 case EXT4_IOC_MOVE_EXT: { 425 struct move_extent me; 426 struct fd donor; 427 int err; 428 429 if (!(filp->f_mode & FMODE_READ) || 430 !(filp->f_mode & FMODE_WRITE)) 431 return -EBADF; 432 433 if (copy_from_user(&me, 434 (struct move_extent __user *)arg, sizeof(me))) 435 return -EFAULT; 436 me.moved_len = 0; 437 438 donor = fdget(me.donor_fd); 439 if (!donor.file) 440 return -EBADF; 441 442 if (!(donor.file->f_mode & FMODE_WRITE)) { 443 err = -EBADF; 444 goto mext_out; 445 } 446 447 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 448 EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 449 ext4_msg(sb, KERN_ERR, 450 "Online defrag not supported with bigalloc"); 451 err = -EOPNOTSUPP; 452 goto mext_out; 453 } 454 455 err = mnt_want_write_file(filp); 456 if (err) 457 goto mext_out; 458 459 err = ext4_move_extents(filp, donor.file, me.orig_start, 460 me.donor_start, me.len, &me.moved_len); 461 mnt_drop_write_file(filp); 462 463 if (copy_to_user((struct move_extent __user *)arg, 464 &me, sizeof(me))) 465 err = -EFAULT; 466 mext_out: 467 fdput(donor); 468 return err; 469 } 470 471 case EXT4_IOC_GROUP_ADD: { 472 struct ext4_new_group_data input; 473 int err, err2=0; 474 475 err = ext4_resize_begin(sb); 476 if (err) 477 return err; 478 479 if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg, 480 sizeof(input))) { 481 err = -EFAULT; 482 goto group_add_out; 483 } 484 485 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 486 EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 487 ext4_msg(sb, KERN_ERR, 488 "Online resizing not supported with bigalloc"); 489 err = -EOPNOTSUPP; 490 goto group_add_out; 491 } 492 493 err = mnt_want_write_file(filp); 494 if (err) 495 goto group_add_out; 496 497 err = ext4_group_add(sb, &input); 498 if (EXT4_SB(sb)->s_journal) { 499 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 500 err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 501 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 502 } 503 if (err == 0) 504 err = err2; 505 mnt_drop_write_file(filp); 506 if (!err && ext4_has_group_desc_csum(sb) && 507 test_opt(sb, INIT_INODE_TABLE)) 508 err = ext4_register_li_request(sb, input.group); 509 group_add_out: 510 ext4_resize_end(sb); 511 return err; 512 } 513 514 case EXT4_IOC_MIGRATE: 515 { 516 int err; 517 if (!inode_owner_or_capable(inode)) 518 return -EACCES; 519 520 err = mnt_want_write_file(filp); 521 if (err) 522 return err; 523 /* 524 * inode_mutex prevent write and truncate on the file. 525 * Read still goes through. We take i_data_sem in 526 * ext4_ext_swap_inode_data before we switch the 527 * inode format to prevent read. 528 */ 529 mutex_lock(&(inode->i_mutex)); 530 err = ext4_ext_migrate(inode); 531 mutex_unlock(&(inode->i_mutex)); 532 mnt_drop_write_file(filp); 533 return err; 534 } 535 536 case EXT4_IOC_ALLOC_DA_BLKS: 537 { 538 int err; 539 if (!inode_owner_or_capable(inode)) 540 return -EACCES; 541 542 err = mnt_want_write_file(filp); 543 if (err) 544 return err; 545 err = ext4_alloc_da_blocks(inode); 546 mnt_drop_write_file(filp); 547 return err; 548 } 549 550 case EXT4_IOC_SWAP_BOOT: 551 if (!(filp->f_mode & FMODE_WRITE)) 552 return -EBADF; 553 return swap_inode_boot_loader(sb, inode); 554 555 case EXT4_IOC_RESIZE_FS: { 556 ext4_fsblk_t n_blocks_count; 557 int err = 0, err2 = 0; 558 ext4_group_t o_group = EXT4_SB(sb)->s_groups_count; 559 560 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 561 EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 562 ext4_msg(sb, KERN_ERR, 563 "Online resizing not (yet) supported with bigalloc"); 564 return -EOPNOTSUPP; 565 } 566 567 if (copy_from_user(&n_blocks_count, (__u64 __user *)arg, 568 sizeof(__u64))) { 569 return -EFAULT; 570 } 571 572 err = ext4_resize_begin(sb); 573 if (err) 574 return err; 575 576 err = mnt_want_write_file(filp); 577 if (err) 578 goto resizefs_out; 579 580 err = ext4_resize_fs(sb, n_blocks_count); 581 if (EXT4_SB(sb)->s_journal) { 582 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 583 err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 584 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 585 } 586 if (err == 0) 587 err = err2; 588 mnt_drop_write_file(filp); 589 if (!err && (o_group > EXT4_SB(sb)->s_groups_count) && 590 ext4_has_group_desc_csum(sb) && 591 test_opt(sb, INIT_INODE_TABLE)) 592 err = ext4_register_li_request(sb, o_group); 593 594 resizefs_out: 595 ext4_resize_end(sb); 596 return err; 597 } 598 599 case FITRIM: 600 { 601 struct request_queue *q = bdev_get_queue(sb->s_bdev); 602 struct fstrim_range range; 603 int ret = 0; 604 605 if (!capable(CAP_SYS_ADMIN)) 606 return -EPERM; 607 608 if (!blk_queue_discard(q)) 609 return -EOPNOTSUPP; 610 611 if (copy_from_user(&range, (struct fstrim_range __user *)arg, 612 sizeof(range))) 613 return -EFAULT; 614 615 range.minlen = max((unsigned int)range.minlen, 616 q->limits.discard_granularity); 617 ret = ext4_trim_fs(sb, &range); 618 if (ret < 0) 619 return ret; 620 621 if (copy_to_user((struct fstrim_range __user *)arg, &range, 622 sizeof(range))) 623 return -EFAULT; 624 625 return 0; 626 } 627 628 default: 629 return -ENOTTY; 630 } 631 } 632 633 #ifdef CONFIG_COMPAT 634 long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 635 { 636 /* These are just misnamed, they actually get/put from/to user an int */ 637 switch (cmd) { 638 case EXT4_IOC32_GETFLAGS: 639 cmd = EXT4_IOC_GETFLAGS; 640 break; 641 case EXT4_IOC32_SETFLAGS: 642 cmd = EXT4_IOC_SETFLAGS; 643 break; 644 case EXT4_IOC32_GETVERSION: 645 cmd = EXT4_IOC_GETVERSION; 646 break; 647 case EXT4_IOC32_SETVERSION: 648 cmd = EXT4_IOC_SETVERSION; 649 break; 650 case EXT4_IOC32_GROUP_EXTEND: 651 cmd = EXT4_IOC_GROUP_EXTEND; 652 break; 653 case EXT4_IOC32_GETVERSION_OLD: 654 cmd = EXT4_IOC_GETVERSION_OLD; 655 break; 656 case EXT4_IOC32_SETVERSION_OLD: 657 cmd = EXT4_IOC_SETVERSION_OLD; 658 break; 659 case EXT4_IOC32_GETRSVSZ: 660 cmd = EXT4_IOC_GETRSVSZ; 661 break; 662 case EXT4_IOC32_SETRSVSZ: 663 cmd = EXT4_IOC_SETRSVSZ; 664 break; 665 case EXT4_IOC32_GROUP_ADD: { 666 struct compat_ext4_new_group_input __user *uinput; 667 struct ext4_new_group_input input; 668 mm_segment_t old_fs; 669 int err; 670 671 uinput = compat_ptr(arg); 672 err = get_user(input.group, &uinput->group); 673 err |= get_user(input.block_bitmap, &uinput->block_bitmap); 674 err |= get_user(input.inode_bitmap, &uinput->inode_bitmap); 675 err |= get_user(input.inode_table, &uinput->inode_table); 676 err |= get_user(input.blocks_count, &uinput->blocks_count); 677 err |= get_user(input.reserved_blocks, 678 &uinput->reserved_blocks); 679 if (err) 680 return -EFAULT; 681 old_fs = get_fs(); 682 set_fs(KERNEL_DS); 683 err = ext4_ioctl(file, EXT4_IOC_GROUP_ADD, 684 (unsigned long) &input); 685 set_fs(old_fs); 686 return err; 687 } 688 case EXT4_IOC_MOVE_EXT: 689 case FITRIM: 690 case EXT4_IOC_RESIZE_FS: 691 break; 692 default: 693 return -ENOIOCTLCMD; 694 } 695 return ext4_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); 696 } 697 #endif 698