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