1ac27a0ecSDave Kleikamp /* 2617ba13bSMingming Cao * linux/fs/ext4/ioctl.c 3ac27a0ecSDave Kleikamp * 4ac27a0ecSDave Kleikamp * Copyright (C) 1993, 1994, 1995 5ac27a0ecSDave Kleikamp * Remy Card (card@masi.ibp.fr) 6ac27a0ecSDave Kleikamp * Laboratoire MASI - Institut Blaise Pascal 7ac27a0ecSDave Kleikamp * Universite Pierre et Marie Curie (Paris VI) 8ac27a0ecSDave Kleikamp */ 9ac27a0ecSDave Kleikamp 10ac27a0ecSDave Kleikamp #include <linux/fs.h> 11dab291afSMingming Cao #include <linux/jbd2.h> 12ac27a0ecSDave Kleikamp #include <linux/capability.h> 13ac27a0ecSDave Kleikamp #include <linux/time.h> 14ac27a0ecSDave Kleikamp #include <linux/compat.h> 1542a74f20SDave Hansen #include <linux/mount.h> 16748de673SAkira Fujita #include <linux/file.h> 17ac27a0ecSDave Kleikamp #include <asm/uaccess.h> 183dcf5451SChristoph Hellwig #include "ext4_jbd2.h" 193dcf5451SChristoph Hellwig #include "ext4.h" 20393d1d1dSDr. Tilmann Bubeck #include "ext4_extents.h" 21ac27a0ecSDave Kleikamp 2219c5246dSYongqiang Yang #define MAX_32_NUM ((((unsigned long long) 1) << 32) - 1) 2319c5246dSYongqiang Yang 24393d1d1dSDr. Tilmann Bubeck /** 25393d1d1dSDr. Tilmann Bubeck * Swap memory between @a and @b for @len bytes. 26393d1d1dSDr. Tilmann Bubeck * 27393d1d1dSDr. Tilmann Bubeck * @a: pointer to first memory area 28393d1d1dSDr. Tilmann Bubeck * @b: pointer to second memory area 29393d1d1dSDr. Tilmann Bubeck * @len: number of bytes to swap 30393d1d1dSDr. Tilmann Bubeck * 31393d1d1dSDr. Tilmann Bubeck */ 32393d1d1dSDr. Tilmann Bubeck static void memswap(void *a, void *b, size_t len) 33393d1d1dSDr. Tilmann Bubeck { 34393d1d1dSDr. Tilmann Bubeck unsigned char *ap, *bp; 35393d1d1dSDr. Tilmann Bubeck unsigned char tmp; 36393d1d1dSDr. Tilmann Bubeck 37393d1d1dSDr. Tilmann Bubeck ap = (unsigned char *)a; 38393d1d1dSDr. Tilmann Bubeck bp = (unsigned char *)b; 39393d1d1dSDr. Tilmann Bubeck while (len-- > 0) { 40393d1d1dSDr. Tilmann Bubeck tmp = *ap; 41393d1d1dSDr. Tilmann Bubeck *ap = *bp; 42393d1d1dSDr. Tilmann Bubeck *bp = tmp; 43393d1d1dSDr. Tilmann Bubeck ap++; 44393d1d1dSDr. Tilmann Bubeck bp++; 45393d1d1dSDr. Tilmann Bubeck } 46393d1d1dSDr. Tilmann Bubeck } 47393d1d1dSDr. Tilmann Bubeck 48393d1d1dSDr. Tilmann Bubeck /** 49393d1d1dSDr. Tilmann Bubeck * Swap i_data and associated attributes between @inode1 and @inode2. 50393d1d1dSDr. Tilmann Bubeck * This function is used for the primary swap between inode1 and inode2 51393d1d1dSDr. Tilmann Bubeck * and also to revert this primary swap in case of errors. 52393d1d1dSDr. Tilmann Bubeck * 53393d1d1dSDr. Tilmann Bubeck * Therefore you have to make sure, that calling this method twice 54393d1d1dSDr. Tilmann Bubeck * will revert all changes. 55393d1d1dSDr. Tilmann Bubeck * 56393d1d1dSDr. Tilmann Bubeck * @inode1: pointer to first inode 57393d1d1dSDr. Tilmann Bubeck * @inode2: pointer to second inode 58393d1d1dSDr. Tilmann Bubeck */ 59393d1d1dSDr. Tilmann Bubeck static void swap_inode_data(struct inode *inode1, struct inode *inode2) 60393d1d1dSDr. Tilmann Bubeck { 61393d1d1dSDr. Tilmann Bubeck loff_t isize; 62393d1d1dSDr. Tilmann Bubeck struct ext4_inode_info *ei1; 63393d1d1dSDr. Tilmann Bubeck struct ext4_inode_info *ei2; 64393d1d1dSDr. Tilmann Bubeck 65393d1d1dSDr. Tilmann Bubeck ei1 = EXT4_I(inode1); 66393d1d1dSDr. Tilmann Bubeck ei2 = EXT4_I(inode2); 67393d1d1dSDr. Tilmann Bubeck 68393d1d1dSDr. Tilmann Bubeck memswap(&inode1->i_flags, &inode2->i_flags, sizeof(inode1->i_flags)); 69393d1d1dSDr. Tilmann Bubeck memswap(&inode1->i_version, &inode2->i_version, 70393d1d1dSDr. Tilmann Bubeck sizeof(inode1->i_version)); 71393d1d1dSDr. Tilmann Bubeck memswap(&inode1->i_blocks, &inode2->i_blocks, 72393d1d1dSDr. Tilmann Bubeck sizeof(inode1->i_blocks)); 73393d1d1dSDr. Tilmann Bubeck memswap(&inode1->i_bytes, &inode2->i_bytes, sizeof(inode1->i_bytes)); 74393d1d1dSDr. Tilmann Bubeck memswap(&inode1->i_atime, &inode2->i_atime, sizeof(inode1->i_atime)); 75393d1d1dSDr. Tilmann Bubeck memswap(&inode1->i_mtime, &inode2->i_mtime, sizeof(inode1->i_mtime)); 76393d1d1dSDr. Tilmann Bubeck 77393d1d1dSDr. Tilmann Bubeck memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data)); 78393d1d1dSDr. Tilmann Bubeck memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags)); 79393d1d1dSDr. Tilmann Bubeck memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize)); 80cde2d7a7STheodore Ts'o ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS); 81cde2d7a7STheodore Ts'o ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS); 82cde2d7a7STheodore Ts'o ext4_es_lru_del(inode1); 83cde2d7a7STheodore Ts'o ext4_es_lru_del(inode2); 84393d1d1dSDr. Tilmann Bubeck 85393d1d1dSDr. Tilmann Bubeck isize = i_size_read(inode1); 86393d1d1dSDr. Tilmann Bubeck i_size_write(inode1, i_size_read(inode2)); 87393d1d1dSDr. Tilmann Bubeck i_size_write(inode2, isize); 88393d1d1dSDr. Tilmann Bubeck } 89393d1d1dSDr. Tilmann Bubeck 90393d1d1dSDr. Tilmann Bubeck /** 91393d1d1dSDr. Tilmann Bubeck * Swap the information from the given @inode and the inode 92393d1d1dSDr. Tilmann Bubeck * EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other 93393d1d1dSDr. Tilmann Bubeck * important fields of the inodes. 94393d1d1dSDr. Tilmann Bubeck * 95393d1d1dSDr. Tilmann Bubeck * @sb: the super block of the filesystem 96393d1d1dSDr. Tilmann Bubeck * @inode: the inode to swap with EXT4_BOOT_LOADER_INO 97393d1d1dSDr. Tilmann Bubeck * 98393d1d1dSDr. Tilmann Bubeck */ 99393d1d1dSDr. Tilmann Bubeck static long swap_inode_boot_loader(struct super_block *sb, 100393d1d1dSDr. Tilmann Bubeck struct inode *inode) 101393d1d1dSDr. Tilmann Bubeck { 102393d1d1dSDr. Tilmann Bubeck handle_t *handle; 103393d1d1dSDr. Tilmann Bubeck int err; 104393d1d1dSDr. Tilmann Bubeck struct inode *inode_bl; 105393d1d1dSDr. Tilmann Bubeck struct ext4_inode_info *ei; 106393d1d1dSDr. Tilmann Bubeck struct ext4_inode_info *ei_bl; 107393d1d1dSDr. Tilmann Bubeck struct ext4_sb_info *sbi; 108393d1d1dSDr. Tilmann Bubeck 109393d1d1dSDr. Tilmann Bubeck if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode)) { 110393d1d1dSDr. Tilmann Bubeck err = -EINVAL; 111393d1d1dSDr. Tilmann Bubeck goto swap_boot_out; 112393d1d1dSDr. Tilmann Bubeck } 113393d1d1dSDr. Tilmann Bubeck 114393d1d1dSDr. Tilmann Bubeck if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN)) { 115393d1d1dSDr. Tilmann Bubeck err = -EPERM; 116393d1d1dSDr. Tilmann Bubeck goto swap_boot_out; 117393d1d1dSDr. Tilmann Bubeck } 118393d1d1dSDr. Tilmann Bubeck 119393d1d1dSDr. Tilmann Bubeck sbi = EXT4_SB(sb); 120393d1d1dSDr. Tilmann Bubeck ei = EXT4_I(inode); 121393d1d1dSDr. Tilmann Bubeck 122393d1d1dSDr. Tilmann Bubeck inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO); 123393d1d1dSDr. Tilmann Bubeck if (IS_ERR(inode_bl)) { 124393d1d1dSDr. Tilmann Bubeck err = PTR_ERR(inode_bl); 125393d1d1dSDr. Tilmann Bubeck goto swap_boot_out; 126393d1d1dSDr. Tilmann Bubeck } 127393d1d1dSDr. Tilmann Bubeck ei_bl = EXT4_I(inode_bl); 128393d1d1dSDr. Tilmann Bubeck 129393d1d1dSDr. Tilmann Bubeck filemap_flush(inode->i_mapping); 130393d1d1dSDr. Tilmann Bubeck filemap_flush(inode_bl->i_mapping); 131393d1d1dSDr. Tilmann Bubeck 132393d1d1dSDr. Tilmann Bubeck /* Protect orig inodes against a truncate and make sure, 133393d1d1dSDr. Tilmann Bubeck * that only 1 swap_inode_boot_loader is running. */ 134393d1d1dSDr. Tilmann Bubeck ext4_inode_double_lock(inode, inode_bl); 135393d1d1dSDr. Tilmann Bubeck 136393d1d1dSDr. Tilmann Bubeck truncate_inode_pages(&inode->i_data, 0); 137393d1d1dSDr. Tilmann Bubeck truncate_inode_pages(&inode_bl->i_data, 0); 138393d1d1dSDr. Tilmann Bubeck 139393d1d1dSDr. Tilmann Bubeck /* Wait for all existing dio workers */ 140393d1d1dSDr. Tilmann Bubeck ext4_inode_block_unlocked_dio(inode); 141393d1d1dSDr. Tilmann Bubeck ext4_inode_block_unlocked_dio(inode_bl); 142393d1d1dSDr. Tilmann Bubeck inode_dio_wait(inode); 143393d1d1dSDr. Tilmann Bubeck inode_dio_wait(inode_bl); 144393d1d1dSDr. Tilmann Bubeck 145393d1d1dSDr. Tilmann Bubeck handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2); 146393d1d1dSDr. Tilmann Bubeck if (IS_ERR(handle)) { 147393d1d1dSDr. Tilmann Bubeck err = -EINVAL; 148393d1d1dSDr. Tilmann Bubeck goto swap_boot_out; 149393d1d1dSDr. Tilmann Bubeck } 150393d1d1dSDr. Tilmann Bubeck 151393d1d1dSDr. Tilmann Bubeck /* Protect extent tree against block allocations via delalloc */ 152393d1d1dSDr. Tilmann Bubeck ext4_double_down_write_data_sem(inode, inode_bl); 153393d1d1dSDr. Tilmann Bubeck 154393d1d1dSDr. Tilmann Bubeck if (inode_bl->i_nlink == 0) { 155393d1d1dSDr. Tilmann Bubeck /* this inode has never been used as a BOOT_LOADER */ 156393d1d1dSDr. Tilmann Bubeck set_nlink(inode_bl, 1); 157393d1d1dSDr. Tilmann Bubeck i_uid_write(inode_bl, 0); 158393d1d1dSDr. Tilmann Bubeck i_gid_write(inode_bl, 0); 159393d1d1dSDr. Tilmann Bubeck inode_bl->i_flags = 0; 160393d1d1dSDr. Tilmann Bubeck ei_bl->i_flags = 0; 161393d1d1dSDr. Tilmann Bubeck inode_bl->i_version = 1; 162393d1d1dSDr. Tilmann Bubeck i_size_write(inode_bl, 0); 163393d1d1dSDr. Tilmann Bubeck inode_bl->i_mode = S_IFREG; 164393d1d1dSDr. Tilmann Bubeck if (EXT4_HAS_INCOMPAT_FEATURE(sb, 165393d1d1dSDr. Tilmann Bubeck EXT4_FEATURE_INCOMPAT_EXTENTS)) { 166393d1d1dSDr. Tilmann Bubeck ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS); 167393d1d1dSDr. Tilmann Bubeck ext4_ext_tree_init(handle, inode_bl); 168393d1d1dSDr. Tilmann Bubeck } else 169393d1d1dSDr. Tilmann Bubeck memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data)); 170393d1d1dSDr. Tilmann Bubeck } 171393d1d1dSDr. Tilmann Bubeck 172393d1d1dSDr. Tilmann Bubeck swap_inode_data(inode, inode_bl); 173393d1d1dSDr. Tilmann Bubeck 174393d1d1dSDr. Tilmann Bubeck inode->i_ctime = inode_bl->i_ctime = ext4_current_time(inode); 175393d1d1dSDr. Tilmann Bubeck 176393d1d1dSDr. Tilmann Bubeck spin_lock(&sbi->s_next_gen_lock); 177393d1d1dSDr. Tilmann Bubeck inode->i_generation = sbi->s_next_generation++; 178393d1d1dSDr. Tilmann Bubeck inode_bl->i_generation = sbi->s_next_generation++; 179393d1d1dSDr. Tilmann Bubeck spin_unlock(&sbi->s_next_gen_lock); 180393d1d1dSDr. Tilmann Bubeck 181393d1d1dSDr. Tilmann Bubeck ext4_discard_preallocations(inode); 182393d1d1dSDr. Tilmann Bubeck 183393d1d1dSDr. Tilmann Bubeck err = ext4_mark_inode_dirty(handle, inode); 184393d1d1dSDr. Tilmann Bubeck if (err < 0) { 185393d1d1dSDr. Tilmann Bubeck ext4_warning(inode->i_sb, 186393d1d1dSDr. Tilmann Bubeck "couldn't mark inode #%lu dirty (err %d)", 187393d1d1dSDr. Tilmann Bubeck inode->i_ino, err); 188393d1d1dSDr. Tilmann Bubeck /* Revert all changes: */ 189393d1d1dSDr. Tilmann Bubeck swap_inode_data(inode, inode_bl); 190393d1d1dSDr. Tilmann Bubeck } else { 191393d1d1dSDr. Tilmann Bubeck err = ext4_mark_inode_dirty(handle, inode_bl); 192393d1d1dSDr. Tilmann Bubeck if (err < 0) { 193393d1d1dSDr. Tilmann Bubeck ext4_warning(inode_bl->i_sb, 194393d1d1dSDr. Tilmann Bubeck "couldn't mark inode #%lu dirty (err %d)", 195393d1d1dSDr. Tilmann Bubeck inode_bl->i_ino, err); 196393d1d1dSDr. Tilmann Bubeck /* Revert all changes: */ 197393d1d1dSDr. Tilmann Bubeck swap_inode_data(inode, inode_bl); 198393d1d1dSDr. Tilmann Bubeck ext4_mark_inode_dirty(handle, inode); 199393d1d1dSDr. Tilmann Bubeck } 200393d1d1dSDr. Tilmann Bubeck } 201393d1d1dSDr. Tilmann Bubeck 202393d1d1dSDr. Tilmann Bubeck ext4_journal_stop(handle); 203393d1d1dSDr. Tilmann Bubeck 204393d1d1dSDr. Tilmann Bubeck ext4_double_up_write_data_sem(inode, inode_bl); 205393d1d1dSDr. Tilmann Bubeck 206393d1d1dSDr. Tilmann Bubeck ext4_inode_resume_unlocked_dio(inode); 207393d1d1dSDr. Tilmann Bubeck ext4_inode_resume_unlocked_dio(inode_bl); 208393d1d1dSDr. Tilmann Bubeck 209393d1d1dSDr. Tilmann Bubeck ext4_inode_double_unlock(inode, inode_bl); 210393d1d1dSDr. Tilmann Bubeck 211393d1d1dSDr. Tilmann Bubeck iput(inode_bl); 212393d1d1dSDr. Tilmann Bubeck 213393d1d1dSDr. Tilmann Bubeck swap_boot_out: 214393d1d1dSDr. Tilmann Bubeck return err; 215393d1d1dSDr. Tilmann Bubeck } 216393d1d1dSDr. Tilmann Bubeck 2175cdd7b2dSAndi Kleen long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 218ac27a0ecSDave Kleikamp { 219496ad9aaSAl Viro struct inode *inode = file_inode(filp); 220bab08ab9STheodore Ts'o struct super_block *sb = inode->i_sb; 221617ba13bSMingming Cao struct ext4_inode_info *ei = EXT4_I(inode); 222ac27a0ecSDave Kleikamp unsigned int flags; 223ac27a0ecSDave Kleikamp 224617ba13bSMingming Cao ext4_debug("cmd = %u, arg = %lu\n", cmd, arg); 225ac27a0ecSDave Kleikamp 226ac27a0ecSDave Kleikamp switch (cmd) { 227617ba13bSMingming Cao case EXT4_IOC_GETFLAGS: 228ff9ddf7eSJan Kara ext4_get_inode_flags(ei); 229617ba13bSMingming Cao flags = ei->i_flags & EXT4_FL_USER_VISIBLE; 230ac27a0ecSDave Kleikamp return put_user(flags, (int __user *) arg); 231617ba13bSMingming Cao case EXT4_IOC_SETFLAGS: { 232ac27a0ecSDave Kleikamp handle_t *handle = NULL; 2334db46fc2SAneesh Kumar K.V int err, migrate = 0; 234617ba13bSMingming Cao struct ext4_iloc iloc; 23579906964STheodore Ts'o unsigned int oldflags, mask, i; 236ac27a0ecSDave Kleikamp unsigned int jflag; 237ac27a0ecSDave Kleikamp 2382e149670SSerge E. Hallyn if (!inode_owner_or_capable(inode)) 239ac27a0ecSDave Kleikamp return -EACCES; 240ac27a0ecSDave Kleikamp 241ac27a0ecSDave Kleikamp if (get_user(flags, (int __user *) arg)) 242ac27a0ecSDave Kleikamp return -EFAULT; 243ac27a0ecSDave Kleikamp 244a561be71SAl Viro err = mnt_want_write_file(filp); 24542a74f20SDave Hansen if (err) 24642a74f20SDave Hansen return err; 24742a74f20SDave Hansen 2482dc6b0d4SDuane Griffin flags = ext4_mask_flags(inode->i_mode, flags); 249ac27a0ecSDave Kleikamp 25042a74f20SDave Hansen err = -EPERM; 251ac27a0ecSDave Kleikamp mutex_lock(&inode->i_mutex); 252e47776a0SJan Kara /* Is it quota file? Do not allow user to mess with it */ 25342a74f20SDave Hansen if (IS_NOQUOTA(inode)) 25442a74f20SDave Hansen goto flags_out; 25542a74f20SDave Hansen 256ac27a0ecSDave Kleikamp oldflags = ei->i_flags; 257ac27a0ecSDave Kleikamp 258ac27a0ecSDave Kleikamp /* The JOURNAL_DATA flag is modifiable only by root */ 259617ba13bSMingming Cao jflag = flags & EXT4_JOURNAL_DATA_FL; 260ac27a0ecSDave Kleikamp 261ac27a0ecSDave Kleikamp /* 262ac27a0ecSDave Kleikamp * The IMMUTABLE and APPEND_ONLY flags can only be changed by 263ac27a0ecSDave Kleikamp * the relevant capability. 264ac27a0ecSDave Kleikamp * 265ac27a0ecSDave Kleikamp * This test looks nicer. Thanks to Pauline Middelink 266ac27a0ecSDave Kleikamp */ 267617ba13bSMingming Cao if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { 26842a74f20SDave Hansen if (!capable(CAP_LINUX_IMMUTABLE)) 26942a74f20SDave Hansen goto flags_out; 270ac27a0ecSDave Kleikamp } 271ac27a0ecSDave Kleikamp 272ac27a0ecSDave Kleikamp /* 273ac27a0ecSDave Kleikamp * The JOURNAL_DATA flag can only be changed by 274ac27a0ecSDave Kleikamp * the relevant capability. 275ac27a0ecSDave Kleikamp */ 276617ba13bSMingming Cao if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { 27742a74f20SDave Hansen if (!capable(CAP_SYS_RESOURCE)) 27842a74f20SDave Hansen goto flags_out; 279ac27a0ecSDave Kleikamp } 280996bb9fdSTheodore Ts'o if ((flags ^ oldflags) & EXT4_EXTENTS_FL) 2814db46fc2SAneesh Kumar K.V migrate = 1; 282ac27a0ecSDave Kleikamp 283c8d46e41SJiaying Zhang if (flags & EXT4_EOFBLOCKS_FL) { 284c8d46e41SJiaying Zhang /* we don't support adding EOFBLOCKS flag */ 285c8d46e41SJiaying Zhang if (!(oldflags & EXT4_EOFBLOCKS_FL)) { 286c8d46e41SJiaying Zhang err = -EOPNOTSUPP; 287c8d46e41SJiaying Zhang goto flags_out; 288c8d46e41SJiaying Zhang } 289c8d46e41SJiaying Zhang } else if (oldflags & EXT4_EOFBLOCKS_FL) 290c8d46e41SJiaying Zhang ext4_truncate(inode); 291c8d46e41SJiaying Zhang 2929924a92aSTheodore Ts'o handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); 293ac27a0ecSDave Kleikamp if (IS_ERR(handle)) { 29442a74f20SDave Hansen err = PTR_ERR(handle); 29542a74f20SDave Hansen goto flags_out; 296ac27a0ecSDave Kleikamp } 297ac27a0ecSDave Kleikamp if (IS_SYNC(inode)) 2980390131bSFrank Mayhar ext4_handle_sync(handle); 299617ba13bSMingming Cao err = ext4_reserve_inode_write(handle, inode, &iloc); 300ac27a0ecSDave Kleikamp if (err) 301ac27a0ecSDave Kleikamp goto flags_err; 302ac27a0ecSDave Kleikamp 30379906964STheodore Ts'o for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { 30479906964STheodore Ts'o if (!(mask & EXT4_FL_USER_MODIFIABLE)) 30579906964STheodore Ts'o continue; 30679906964STheodore Ts'o if (mask & flags) 30779906964STheodore Ts'o ext4_set_inode_flag(inode, i); 30879906964STheodore Ts'o else 30979906964STheodore Ts'o ext4_clear_inode_flag(inode, i); 31079906964STheodore Ts'o } 311ac27a0ecSDave Kleikamp 312617ba13bSMingming Cao ext4_set_inode_flags(inode); 313ef7f3835SKalpak Shah inode->i_ctime = ext4_current_time(inode); 314ac27a0ecSDave Kleikamp 315617ba13bSMingming Cao err = ext4_mark_iloc_dirty(handle, inode, &iloc); 316ac27a0ecSDave Kleikamp flags_err: 317617ba13bSMingming Cao ext4_journal_stop(handle); 31842a74f20SDave Hansen if (err) 31942a74f20SDave Hansen goto flags_out; 320ac27a0ecSDave Kleikamp 321617ba13bSMingming Cao if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) 322617ba13bSMingming Cao err = ext4_change_inode_journal_flag(inode, jflag); 3234db46fc2SAneesh Kumar K.V if (err) 3244db46fc2SAneesh Kumar K.V goto flags_out; 325996bb9fdSTheodore Ts'o if (migrate) { 326996bb9fdSTheodore Ts'o if (flags & EXT4_EXTENTS_FL) 3274db46fc2SAneesh Kumar K.V err = ext4_ext_migrate(inode); 328996bb9fdSTheodore Ts'o else 329996bb9fdSTheodore Ts'o err = ext4_ind_migrate(inode); 330996bb9fdSTheodore Ts'o } 331996bb9fdSTheodore Ts'o 33242a74f20SDave Hansen flags_out: 333ac27a0ecSDave Kleikamp mutex_unlock(&inode->i_mutex); 3342a79f17eSAl Viro mnt_drop_write_file(filp); 335ac27a0ecSDave Kleikamp return err; 336ac27a0ecSDave Kleikamp } 337617ba13bSMingming Cao case EXT4_IOC_GETVERSION: 338617ba13bSMingming Cao case EXT4_IOC_GETVERSION_OLD: 339ac27a0ecSDave Kleikamp return put_user(inode->i_generation, (int __user *) arg); 340617ba13bSMingming Cao case EXT4_IOC_SETVERSION: 341617ba13bSMingming Cao case EXT4_IOC_SETVERSION_OLD: { 342ac27a0ecSDave Kleikamp handle_t *handle; 343617ba13bSMingming Cao struct ext4_iloc iloc; 344ac27a0ecSDave Kleikamp __u32 generation; 345ac27a0ecSDave Kleikamp int err; 346ac27a0ecSDave Kleikamp 3472e149670SSerge E. Hallyn if (!inode_owner_or_capable(inode)) 348ac27a0ecSDave Kleikamp return -EPERM; 34942a74f20SDave Hansen 350814525f4SDarrick J. Wong if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb, 351814525f4SDarrick J. Wong EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { 352814525f4SDarrick J. Wong ext4_warning(sb, "Setting inode version is not " 353814525f4SDarrick J. Wong "supported with metadata_csum enabled."); 354814525f4SDarrick J. Wong return -ENOTTY; 355814525f4SDarrick J. Wong } 356814525f4SDarrick J. Wong 357a561be71SAl Viro err = mnt_want_write_file(filp); 35842a74f20SDave Hansen if (err) 35942a74f20SDave Hansen return err; 36042a74f20SDave Hansen if (get_user(generation, (int __user *) arg)) { 36142a74f20SDave Hansen err = -EFAULT; 36242a74f20SDave Hansen goto setversion_out; 36342a74f20SDave Hansen } 364ac27a0ecSDave Kleikamp 3656c2155b9SDjalal Harouni mutex_lock(&inode->i_mutex); 3669924a92aSTheodore Ts'o handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); 36742a74f20SDave Hansen if (IS_ERR(handle)) { 36842a74f20SDave Hansen err = PTR_ERR(handle); 3696c2155b9SDjalal Harouni goto unlock_out; 37042a74f20SDave Hansen } 371617ba13bSMingming Cao err = ext4_reserve_inode_write(handle, inode, &iloc); 372ac27a0ecSDave Kleikamp if (err == 0) { 373ef7f3835SKalpak Shah inode->i_ctime = ext4_current_time(inode); 374ac27a0ecSDave Kleikamp inode->i_generation = generation; 375617ba13bSMingming Cao err = ext4_mark_iloc_dirty(handle, inode, &iloc); 376ac27a0ecSDave Kleikamp } 377617ba13bSMingming Cao ext4_journal_stop(handle); 3786c2155b9SDjalal Harouni 3796c2155b9SDjalal Harouni unlock_out: 3806c2155b9SDjalal Harouni mutex_unlock(&inode->i_mutex); 38142a74f20SDave Hansen setversion_out: 3822a79f17eSAl Viro mnt_drop_write_file(filp); 383ac27a0ecSDave Kleikamp return err; 384ac27a0ecSDave Kleikamp } 385617ba13bSMingming Cao case EXT4_IOC_GROUP_EXTEND: { 386617ba13bSMingming Cao ext4_fsblk_t n_blocks_count; 387ac046f1dSPeng Tao int err, err2=0; 388ac27a0ecSDave Kleikamp 3898f82f840SYongqiang Yang err = ext4_resize_begin(sb); 3908f82f840SYongqiang Yang if (err) 3918f82f840SYongqiang Yang return err; 392ac27a0ecSDave Kleikamp 393014a1770SDjalal Harouni if (get_user(n_blocks_count, (__u32 __user *)arg)) { 394014a1770SDjalal Harouni err = -EFAULT; 395014a1770SDjalal Harouni goto group_extend_out; 396014a1770SDjalal Harouni } 397ac27a0ecSDave Kleikamp 398bab08ab9STheodore Ts'o if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 399bab08ab9STheodore Ts'o EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 400bab08ab9STheodore Ts'o ext4_msg(sb, KERN_ERR, 401bab08ab9STheodore Ts'o "Online resizing not supported with bigalloc"); 402014a1770SDjalal Harouni err = -EOPNOTSUPP; 403014a1770SDjalal Harouni goto group_extend_out; 404bab08ab9STheodore Ts'o } 405bab08ab9STheodore Ts'o 406a561be71SAl Viro err = mnt_want_write_file(filp); 40742a74f20SDave Hansen if (err) 408014a1770SDjalal Harouni goto group_extend_out; 40942a74f20SDave Hansen 410617ba13bSMingming Cao err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); 411ac046f1dSPeng Tao if (EXT4_SB(sb)->s_journal) { 412dab291afSMingming Cao jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 4137ffe1ea8SHidehiro Kawai err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 414dab291afSMingming Cao jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 415ac046f1dSPeng Tao } 4167ffe1ea8SHidehiro Kawai if (err == 0) 4177ffe1ea8SHidehiro Kawai err = err2; 4182a79f17eSAl Viro mnt_drop_write_file(filp); 419014a1770SDjalal Harouni group_extend_out: 4208f82f840SYongqiang Yang ext4_resize_end(sb); 421ac27a0ecSDave Kleikamp return err; 422ac27a0ecSDave Kleikamp } 423748de673SAkira Fujita 424748de673SAkira Fujita case EXT4_IOC_MOVE_EXT: { 425748de673SAkira Fujita struct move_extent me; 4262903ff01SAl Viro struct fd donor; 4272903ff01SAl Viro int err; 428748de673SAkira Fujita 4294a58579bSAkira Fujita if (!(filp->f_mode & FMODE_READ) || 4304a58579bSAkira Fujita !(filp->f_mode & FMODE_WRITE)) 4314a58579bSAkira Fujita return -EBADF; 4324a58579bSAkira Fujita 433748de673SAkira Fujita if (copy_from_user(&me, 434748de673SAkira Fujita (struct move_extent __user *)arg, sizeof(me))) 435748de673SAkira Fujita return -EFAULT; 4364a58579bSAkira Fujita me.moved_len = 0; 437748de673SAkira Fujita 4382903ff01SAl Viro donor = fdget(me.donor_fd); 4392903ff01SAl Viro if (!donor.file) 440748de673SAkira Fujita return -EBADF; 441748de673SAkira Fujita 4422903ff01SAl Viro if (!(donor.file->f_mode & FMODE_WRITE)) { 4434a58579bSAkira Fujita err = -EBADF; 4444a58579bSAkira Fujita goto mext_out; 445748de673SAkira Fujita } 446748de673SAkira Fujita 447bab08ab9STheodore Ts'o if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 448bab08ab9STheodore Ts'o EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 449bab08ab9STheodore Ts'o ext4_msg(sb, KERN_ERR, 450bab08ab9STheodore Ts'o "Online defrag not supported with bigalloc"); 451399c9b86SAl Viro err = -EOPNOTSUPP; 452399c9b86SAl Viro goto mext_out; 453bab08ab9STheodore Ts'o } 454bab08ab9STheodore Ts'o 455a561be71SAl Viro err = mnt_want_write_file(filp); 4564a58579bSAkira Fujita if (err) 4574a58579bSAkira Fujita goto mext_out; 4584a58579bSAkira Fujita 4592903ff01SAl Viro err = ext4_move_extents(filp, donor.file, me.orig_start, 460748de673SAkira Fujita me.donor_start, me.len, &me.moved_len); 4612a79f17eSAl Viro mnt_drop_write_file(filp); 462748de673SAkira Fujita 463c437b273SAkira Fujita if (copy_to_user((struct move_extent __user *)arg, 464c437b273SAkira Fujita &me, sizeof(me))) 4654a58579bSAkira Fujita err = -EFAULT; 4664a58579bSAkira Fujita mext_out: 4672903ff01SAl Viro fdput(donor); 468748de673SAkira Fujita return err; 469748de673SAkira Fujita } 470748de673SAkira Fujita 471617ba13bSMingming Cao case EXT4_IOC_GROUP_ADD: { 472617ba13bSMingming Cao struct ext4_new_group_data input; 473ac046f1dSPeng Tao int err, err2=0; 474ac27a0ecSDave Kleikamp 4758f82f840SYongqiang Yang err = ext4_resize_begin(sb); 4768f82f840SYongqiang Yang if (err) 4778f82f840SYongqiang Yang return err; 478ac27a0ecSDave Kleikamp 479617ba13bSMingming Cao if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg, 480014a1770SDjalal Harouni sizeof(input))) { 481014a1770SDjalal Harouni err = -EFAULT; 482014a1770SDjalal Harouni goto group_add_out; 483014a1770SDjalal Harouni } 484ac27a0ecSDave Kleikamp 485bab08ab9STheodore Ts'o if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 486bab08ab9STheodore Ts'o EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 487bab08ab9STheodore Ts'o ext4_msg(sb, KERN_ERR, 488bab08ab9STheodore Ts'o "Online resizing not supported with bigalloc"); 489014a1770SDjalal Harouni err = -EOPNOTSUPP; 490014a1770SDjalal Harouni goto group_add_out; 491bab08ab9STheodore Ts'o } 492bab08ab9STheodore Ts'o 493a561be71SAl Viro err = mnt_want_write_file(filp); 49442a74f20SDave Hansen if (err) 495014a1770SDjalal Harouni goto group_add_out; 49642a74f20SDave Hansen 497617ba13bSMingming Cao err = ext4_group_add(sb, &input); 498ac046f1dSPeng Tao if (EXT4_SB(sb)->s_journal) { 499dab291afSMingming Cao jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 5007ffe1ea8SHidehiro Kawai err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 501dab291afSMingming Cao jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 502ac046f1dSPeng Tao } 5037ffe1ea8SHidehiro Kawai if (err == 0) 5047ffe1ea8SHidehiro Kawai err = err2; 5052a79f17eSAl Viro mnt_drop_write_file(filp); 5067f511862STheodore Ts'o if (!err && ext4_has_group_desc_csum(sb) && 5077f511862STheodore Ts'o test_opt(sb, INIT_INODE_TABLE)) 5087f511862STheodore Ts'o err = ext4_register_li_request(sb, input.group); 509014a1770SDjalal Harouni group_add_out: 5108f82f840SYongqiang Yang ext4_resize_end(sb); 511ac27a0ecSDave Kleikamp return err; 512ac27a0ecSDave Kleikamp } 513ac27a0ecSDave Kleikamp 514c14c6fd5SAneesh Kumar K.V case EXT4_IOC_MIGRATE: 5152a43a878SAneesh Kumar K.V { 5162a43a878SAneesh Kumar K.V int err; 5172e149670SSerge E. Hallyn if (!inode_owner_or_capable(inode)) 5182a43a878SAneesh Kumar K.V return -EACCES; 5192a43a878SAneesh Kumar K.V 520a561be71SAl Viro err = mnt_want_write_file(filp); 5212a43a878SAneesh Kumar K.V if (err) 5222a43a878SAneesh Kumar K.V return err; 5232a43a878SAneesh Kumar K.V /* 5242a43a878SAneesh Kumar K.V * inode_mutex prevent write and truncate on the file. 5252a43a878SAneesh Kumar K.V * Read still goes through. We take i_data_sem in 5262a43a878SAneesh Kumar K.V * ext4_ext_swap_inode_data before we switch the 5272a43a878SAneesh Kumar K.V * inode format to prevent read. 5282a43a878SAneesh Kumar K.V */ 5292a43a878SAneesh Kumar K.V mutex_lock(&(inode->i_mutex)); 5302a43a878SAneesh Kumar K.V err = ext4_ext_migrate(inode); 5312a43a878SAneesh Kumar K.V mutex_unlock(&(inode->i_mutex)); 5322a79f17eSAl Viro mnt_drop_write_file(filp); 5332a43a878SAneesh Kumar K.V return err; 5342a43a878SAneesh Kumar K.V } 535c14c6fd5SAneesh Kumar K.V 536ccd2506bSTheodore Ts'o case EXT4_IOC_ALLOC_DA_BLKS: 537ccd2506bSTheodore Ts'o { 538ccd2506bSTheodore Ts'o int err; 5392e149670SSerge E. Hallyn if (!inode_owner_or_capable(inode)) 540ccd2506bSTheodore Ts'o return -EACCES; 541ccd2506bSTheodore Ts'o 542a561be71SAl Viro err = mnt_want_write_file(filp); 543ccd2506bSTheodore Ts'o if (err) 544ccd2506bSTheodore Ts'o return err; 545ccd2506bSTheodore Ts'o err = ext4_alloc_da_blocks(inode); 5462a79f17eSAl Viro mnt_drop_write_file(filp); 547ccd2506bSTheodore Ts'o return err; 548ccd2506bSTheodore Ts'o } 549ccd2506bSTheodore Ts'o 550393d1d1dSDr. Tilmann Bubeck case EXT4_IOC_SWAP_BOOT: 551393d1d1dSDr. Tilmann Bubeck if (!(filp->f_mode & FMODE_WRITE)) 552393d1d1dSDr. Tilmann Bubeck return -EBADF; 553393d1d1dSDr. Tilmann Bubeck return swap_inode_boot_loader(sb, inode); 554393d1d1dSDr. Tilmann Bubeck 55519c5246dSYongqiang Yang case EXT4_IOC_RESIZE_FS: { 55619c5246dSYongqiang Yang ext4_fsblk_t n_blocks_count; 55719c5246dSYongqiang Yang int err = 0, err2 = 0; 5587f511862STheodore Ts'o ext4_group_t o_group = EXT4_SB(sb)->s_groups_count; 55919c5246dSYongqiang Yang 56019c5246dSYongqiang Yang if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 56119c5246dSYongqiang Yang EXT4_FEATURE_RO_COMPAT_BIGALLOC)) { 56219c5246dSYongqiang Yang ext4_msg(sb, KERN_ERR, 56319c5246dSYongqiang Yang "Online resizing not (yet) supported with bigalloc"); 56419c5246dSYongqiang Yang return -EOPNOTSUPP; 56519c5246dSYongqiang Yang } 56619c5246dSYongqiang Yang 56719c5246dSYongqiang Yang if (copy_from_user(&n_blocks_count, (__u64 __user *)arg, 56819c5246dSYongqiang Yang sizeof(__u64))) { 56919c5246dSYongqiang Yang return -EFAULT; 57019c5246dSYongqiang Yang } 57119c5246dSYongqiang Yang 57219c5246dSYongqiang Yang err = ext4_resize_begin(sb); 57319c5246dSYongqiang Yang if (err) 57419c5246dSYongqiang Yang return err; 57519c5246dSYongqiang Yang 5768cae6f71SAl Viro err = mnt_want_write_file(filp); 57719c5246dSYongqiang Yang if (err) 57819c5246dSYongqiang Yang goto resizefs_out; 57919c5246dSYongqiang Yang 58019c5246dSYongqiang Yang err = ext4_resize_fs(sb, n_blocks_count); 58119c5246dSYongqiang Yang if (EXT4_SB(sb)->s_journal) { 58219c5246dSYongqiang Yang jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 58319c5246dSYongqiang Yang err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 58419c5246dSYongqiang Yang jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 58519c5246dSYongqiang Yang } 58619c5246dSYongqiang Yang if (err == 0) 58719c5246dSYongqiang Yang err = err2; 5888cae6f71SAl Viro mnt_drop_write_file(filp); 5897f511862STheodore Ts'o if (!err && (o_group > EXT4_SB(sb)->s_groups_count) && 5907f511862STheodore Ts'o ext4_has_group_desc_csum(sb) && 5917f511862STheodore Ts'o test_opt(sb, INIT_INODE_TABLE)) 5927f511862STheodore Ts'o err = ext4_register_li_request(sb, o_group); 5937f511862STheodore Ts'o 59419c5246dSYongqiang Yang resizefs_out: 59519c5246dSYongqiang Yang ext4_resize_end(sb); 59619c5246dSYongqiang Yang return err; 59719c5246dSYongqiang Yang } 59819c5246dSYongqiang Yang 599e681c047SLukas Czerner case FITRIM: 600e681c047SLukas Czerner { 60141431792SLukas Czerner struct request_queue *q = bdev_get_queue(sb->s_bdev); 602e681c047SLukas Czerner struct fstrim_range range; 603e681c047SLukas Czerner int ret = 0; 604e681c047SLukas Czerner 605e681c047SLukas Czerner if (!capable(CAP_SYS_ADMIN)) 606e681c047SLukas Czerner return -EPERM; 607e681c047SLukas Czerner 60841431792SLukas Czerner if (!blk_queue_discard(q)) 60941431792SLukas Czerner return -EOPNOTSUPP; 61041431792SLukas Czerner 611e6705f7cSH Hartley Sweeten if (copy_from_user(&range, (struct fstrim_range __user *)arg, 612e681c047SLukas Czerner sizeof(range))) 613e681c047SLukas Czerner return -EFAULT; 614e681c047SLukas Czerner 6155c2ed62fSLukas Czerner range.minlen = max((unsigned int)range.minlen, 6165c2ed62fSLukas Czerner q->limits.discard_granularity); 617e681c047SLukas Czerner ret = ext4_trim_fs(sb, &range); 618e681c047SLukas Czerner if (ret < 0) 619e681c047SLukas Czerner return ret; 620e681c047SLukas Czerner 621e6705f7cSH Hartley Sweeten if (copy_to_user((struct fstrim_range __user *)arg, &range, 622e681c047SLukas Czerner sizeof(range))) 623e681c047SLukas Czerner return -EFAULT; 624e681c047SLukas Czerner 625e681c047SLukas Czerner return 0; 626e681c047SLukas Czerner } 627e681c047SLukas Czerner 628ac27a0ecSDave Kleikamp default: 629ac27a0ecSDave Kleikamp return -ENOTTY; 630ac27a0ecSDave Kleikamp } 631ac27a0ecSDave Kleikamp } 632ac27a0ecSDave Kleikamp 633ac27a0ecSDave Kleikamp #ifdef CONFIG_COMPAT 634617ba13bSMingming Cao long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 635ac27a0ecSDave Kleikamp { 636ac27a0ecSDave Kleikamp /* These are just misnamed, they actually get/put from/to user an int */ 637ac27a0ecSDave Kleikamp switch (cmd) { 638617ba13bSMingming Cao case EXT4_IOC32_GETFLAGS: 639617ba13bSMingming Cao cmd = EXT4_IOC_GETFLAGS; 640ac27a0ecSDave Kleikamp break; 641617ba13bSMingming Cao case EXT4_IOC32_SETFLAGS: 642617ba13bSMingming Cao cmd = EXT4_IOC_SETFLAGS; 643ac27a0ecSDave Kleikamp break; 644617ba13bSMingming Cao case EXT4_IOC32_GETVERSION: 645617ba13bSMingming Cao cmd = EXT4_IOC_GETVERSION; 646ac27a0ecSDave Kleikamp break; 647617ba13bSMingming Cao case EXT4_IOC32_SETVERSION: 648617ba13bSMingming Cao cmd = EXT4_IOC_SETVERSION; 649ac27a0ecSDave Kleikamp break; 650617ba13bSMingming Cao case EXT4_IOC32_GROUP_EXTEND: 651617ba13bSMingming Cao cmd = EXT4_IOC_GROUP_EXTEND; 652ac27a0ecSDave Kleikamp break; 653617ba13bSMingming Cao case EXT4_IOC32_GETVERSION_OLD: 654617ba13bSMingming Cao cmd = EXT4_IOC_GETVERSION_OLD; 655ac27a0ecSDave Kleikamp break; 656617ba13bSMingming Cao case EXT4_IOC32_SETVERSION_OLD: 657617ba13bSMingming Cao cmd = EXT4_IOC_SETVERSION_OLD; 658ac27a0ecSDave Kleikamp break; 659617ba13bSMingming Cao case EXT4_IOC32_GETRSVSZ: 660617ba13bSMingming Cao cmd = EXT4_IOC_GETRSVSZ; 661ac27a0ecSDave Kleikamp break; 662617ba13bSMingming Cao case EXT4_IOC32_SETRSVSZ: 663617ba13bSMingming Cao cmd = EXT4_IOC_SETRSVSZ; 664ac27a0ecSDave Kleikamp break; 6654d92dc0fSBen Hutchings case EXT4_IOC32_GROUP_ADD: { 6664d92dc0fSBen Hutchings struct compat_ext4_new_group_input __user *uinput; 6674d92dc0fSBen Hutchings struct ext4_new_group_input input; 6684d92dc0fSBen Hutchings mm_segment_t old_fs; 6694d92dc0fSBen Hutchings int err; 6704d92dc0fSBen Hutchings 6714d92dc0fSBen Hutchings uinput = compat_ptr(arg); 6724d92dc0fSBen Hutchings err = get_user(input.group, &uinput->group); 6734d92dc0fSBen Hutchings err |= get_user(input.block_bitmap, &uinput->block_bitmap); 6744d92dc0fSBen Hutchings err |= get_user(input.inode_bitmap, &uinput->inode_bitmap); 6754d92dc0fSBen Hutchings err |= get_user(input.inode_table, &uinput->inode_table); 6764d92dc0fSBen Hutchings err |= get_user(input.blocks_count, &uinput->blocks_count); 6774d92dc0fSBen Hutchings err |= get_user(input.reserved_blocks, 6784d92dc0fSBen Hutchings &uinput->reserved_blocks); 6794d92dc0fSBen Hutchings if (err) 6804d92dc0fSBen Hutchings return -EFAULT; 6814d92dc0fSBen Hutchings old_fs = get_fs(); 6824d92dc0fSBen Hutchings set_fs(KERNEL_DS); 6834d92dc0fSBen Hutchings err = ext4_ioctl(file, EXT4_IOC_GROUP_ADD, 6844d92dc0fSBen Hutchings (unsigned long) &input); 6854d92dc0fSBen Hutchings set_fs(old_fs); 6864d92dc0fSBen Hutchings return err; 6874d92dc0fSBen Hutchings } 688b684b2eeSChristian Borntraeger case EXT4_IOC_MOVE_EXT: 689a56e69c2STao Ma case FITRIM: 69019c5246dSYongqiang Yang case EXT4_IOC_RESIZE_FS: 691b684b2eeSChristian Borntraeger break; 692ac27a0ecSDave Kleikamp default: 693ac27a0ecSDave Kleikamp return -ENOIOCTLCMD; 694ac27a0ecSDave Kleikamp } 6955cdd7b2dSAndi Kleen return ext4_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); 696ac27a0ecSDave Kleikamp } 697ac27a0ecSDave Kleikamp #endif 698