LCOV - code coverage report
Current view: top level - fs/ext4 - ioctl.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 27 710 3.8 %
Date: 2021-04-22 12:43:58 Functions: 2 18 11.1 %

          Line data    Source code
       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/uuid.h>
      20             : #include <linux/uaccess.h>
      21             : #include <linux/delay.h>
      22             : #include <linux/iversion.h>
      23             : #include "ext4_jbd2.h"
      24             : #include "ext4.h"
      25             : #include <linux/fsmap.h>
      26             : #include "fsmap.h"
      27             : #include <trace/events/ext4.h>
      28             : 
      29             : /**
      30             :  * Swap memory between @a and @b for @len bytes.
      31             :  *
      32             :  * @a:          pointer to first memory area
      33             :  * @b:          pointer to second memory area
      34             :  * @len:        number of bytes to swap
      35             :  *
      36             :  */
      37           0 : static void memswap(void *a, void *b, size_t len)
      38             : {
      39           0 :         unsigned char *ap, *bp;
      40             : 
      41           0 :         ap = (unsigned char *)a;
      42           0 :         bp = (unsigned char *)b;
      43           0 :         while (len-- > 0) {
      44           0 :                 swap(*ap, *bp);
      45           0 :                 ap++;
      46           0 :                 bp++;
      47             :         }
      48             : }
      49             : 
      50             : /**
      51             :  * Swap i_data and associated attributes between @inode1 and @inode2.
      52             :  * This function is used for the primary swap between inode1 and inode2
      53             :  * and also to revert this primary swap in case of errors.
      54             :  *
      55             :  * Therefore you have to make sure, that calling this method twice
      56             :  * will revert all changes.
      57             :  *
      58             :  * @inode1:     pointer to first inode
      59             :  * @inode2:     pointer to second inode
      60             :  */
      61           0 : static void swap_inode_data(struct inode *inode1, struct inode *inode2)
      62             : {
      63           0 :         loff_t isize;
      64           0 :         struct ext4_inode_info *ei1;
      65           0 :         struct ext4_inode_info *ei2;
      66           0 :         unsigned long tmp;
      67             : 
      68           0 :         ei1 = EXT4_I(inode1);
      69           0 :         ei2 = EXT4_I(inode2);
      70             : 
      71           0 :         swap(inode1->i_version, inode2->i_version);
      72           0 :         swap(inode1->i_atime, inode2->i_atime);
      73           0 :         swap(inode1->i_mtime, inode2->i_mtime);
      74             : 
      75           0 :         memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
      76           0 :         tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP;
      77           0 :         ei1->i_flags = (ei2->i_flags & EXT4_FL_SHOULD_SWAP) |
      78           0 :                 (ei1->i_flags & ~EXT4_FL_SHOULD_SWAP);
      79           0 :         ei2->i_flags = tmp | (ei2->i_flags & ~EXT4_FL_SHOULD_SWAP);
      80           0 :         swap(ei1->i_disksize, ei2->i_disksize);
      81           0 :         ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS);
      82           0 :         ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS);
      83             : 
      84           0 :         isize = i_size_read(inode1);
      85           0 :         i_size_write(inode1, i_size_read(inode2));
      86           0 :         i_size_write(inode2, isize);
      87           0 : }
      88             : 
      89           0 : void ext4_reset_inode_seed(struct inode *inode)
      90             : {
      91           0 :         struct ext4_inode_info *ei = EXT4_I(inode);
      92           0 :         struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
      93           0 :         __le32 inum = cpu_to_le32(inode->i_ino);
      94           0 :         __le32 gen = cpu_to_le32(inode->i_generation);
      95           0 :         __u32 csum;
      96             : 
      97           0 :         if (!ext4_has_metadata_csum(inode->i_sb))
      98           0 :                 return;
      99             : 
     100           0 :         csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&inum, sizeof(inum));
     101           0 :         ei->i_csum_seed = ext4_chksum(sbi, csum, (__u8 *)&gen, sizeof(gen));
     102             : }
     103             : 
     104             : /**
     105             :  * Swap the information from the given @inode and the inode
     106             :  * EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other
     107             :  * important fields of the inodes.
     108             :  *
     109             :  * @sb:         the super block of the filesystem
     110             :  * @mnt_userns: user namespace of the mount the inode was found from
     111             :  * @inode:      the inode to swap with EXT4_BOOT_LOADER_INO
     112             :  *
     113             :  */
     114           0 : static long swap_inode_boot_loader(struct super_block *sb,
     115             :                                 struct user_namespace *mnt_userns,
     116             :                                 struct inode *inode)
     117             : {
     118           0 :         handle_t *handle;
     119           0 :         int err;
     120           0 :         struct inode *inode_bl;
     121           0 :         struct ext4_inode_info *ei_bl;
     122           0 :         qsize_t size, size_bl, diff;
     123           0 :         blkcnt_t blocks;
     124           0 :         unsigned short bytes;
     125             : 
     126           0 :         inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
     127           0 :         if (IS_ERR(inode_bl))
     128           0 :                 return PTR_ERR(inode_bl);
     129           0 :         ei_bl = EXT4_I(inode_bl);
     130             : 
     131             :         /* Protect orig inodes against a truncate and make sure,
     132             :          * that only 1 swap_inode_boot_loader is running. */
     133           0 :         lock_two_nondirectories(inode, inode_bl);
     134             : 
     135           0 :         if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode) ||
     136           0 :             IS_SWAPFILE(inode) || IS_ENCRYPTED(inode) ||
     137           0 :             (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) ||
     138           0 :             ext4_has_inline_data(inode)) {
     139           0 :                 err = -EINVAL;
     140           0 :                 goto journal_err_out;
     141             :         }
     142             : 
     143           0 :         if (IS_RDONLY(inode) || IS_APPEND(inode) || IS_IMMUTABLE(inode) ||
     144           0 :             !inode_owner_or_capable(mnt_userns, inode) ||
     145           0 :             !capable(CAP_SYS_ADMIN)) {
     146           0 :                 err = -EPERM;
     147           0 :                 goto journal_err_out;
     148             :         }
     149             : 
     150           0 :         down_write(&EXT4_I(inode)->i_mmap_sem);
     151           0 :         err = filemap_write_and_wait(inode->i_mapping);
     152           0 :         if (err)
     153           0 :                 goto err_out;
     154             : 
     155           0 :         err = filemap_write_and_wait(inode_bl->i_mapping);
     156           0 :         if (err)
     157           0 :                 goto err_out;
     158             : 
     159             :         /* Wait for all existing dio workers */
     160           0 :         inode_dio_wait(inode);
     161           0 :         inode_dio_wait(inode_bl);
     162             : 
     163           0 :         truncate_inode_pages(&inode->i_data, 0);
     164           0 :         truncate_inode_pages(&inode_bl->i_data, 0);
     165             : 
     166           0 :         handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
     167           0 :         if (IS_ERR(handle)) {
     168           0 :                 err = -EINVAL;
     169           0 :                 goto err_out;
     170             :         }
     171           0 :         ext4_fc_start_ineligible(sb, EXT4_FC_REASON_SWAP_BOOT);
     172             : 
     173             :         /* Protect extent tree against block allocations via delalloc */
     174           0 :         ext4_double_down_write_data_sem(inode, inode_bl);
     175             : 
     176           0 :         if (inode_bl->i_nlink == 0) {
     177             :                 /* this inode has never been used as a BOOT_LOADER */
     178           0 :                 set_nlink(inode_bl, 1);
     179           0 :                 i_uid_write(inode_bl, 0);
     180           0 :                 i_gid_write(inode_bl, 0);
     181           0 :                 inode_bl->i_flags = 0;
     182           0 :                 ei_bl->i_flags = 0;
     183           0 :                 inode_set_iversion(inode_bl, 1);
     184           0 :                 i_size_write(inode_bl, 0);
     185           0 :                 inode_bl->i_mode = S_IFREG;
     186           0 :                 if (ext4_has_feature_extents(sb)) {
     187           0 :                         ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
     188           0 :                         ext4_ext_tree_init(handle, inode_bl);
     189             :                 } else
     190           0 :                         memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data));
     191             :         }
     192             : 
     193           0 :         err = dquot_initialize(inode);
     194           0 :         if (err)
     195             :                 goto err_out1;
     196             : 
     197           0 :         size = (qsize_t)(inode->i_blocks) * (1 << 9) + inode->i_bytes;
     198           0 :         size_bl = (qsize_t)(inode_bl->i_blocks) * (1 << 9) + inode_bl->i_bytes;
     199           0 :         diff = size - size_bl;
     200           0 :         swap_inode_data(inode, inode_bl);
     201             : 
     202           0 :         inode->i_ctime = inode_bl->i_ctime = current_time(inode);
     203             : 
     204           0 :         inode->i_generation = prandom_u32();
     205           0 :         inode_bl->i_generation = prandom_u32();
     206           0 :         ext4_reset_inode_seed(inode);
     207           0 :         ext4_reset_inode_seed(inode_bl);
     208             : 
     209           0 :         ext4_discard_preallocations(inode, 0);
     210             : 
     211           0 :         err = ext4_mark_inode_dirty(handle, inode);
     212           0 :         if (err < 0) {
     213             :                 /* No need to update quota information. */
     214           0 :                 ext4_warning(inode->i_sb,
     215             :                         "couldn't mark inode #%lu dirty (err %d)",
     216             :                         inode->i_ino, err);
     217             :                 /* Revert all changes: */
     218           0 :                 swap_inode_data(inode, inode_bl);
     219           0 :                 ext4_mark_inode_dirty(handle, inode);
     220           0 :                 goto err_out1;
     221             :         }
     222             : 
     223           0 :         blocks = inode_bl->i_blocks;
     224           0 :         bytes = inode_bl->i_bytes;
     225           0 :         inode_bl->i_blocks = inode->i_blocks;
     226           0 :         inode_bl->i_bytes = inode->i_bytes;
     227           0 :         err = ext4_mark_inode_dirty(handle, inode_bl);
     228           0 :         if (err < 0) {
     229             :                 /* No need to update quota information. */
     230           0 :                 ext4_warning(inode_bl->i_sb,
     231             :                         "couldn't mark inode #%lu dirty (err %d)",
     232             :                         inode_bl->i_ino, err);
     233           0 :                 goto revert;
     234             :         }
     235             : 
     236             :         /* Bootloader inode should not be counted into quota information. */
     237           0 :         if (diff > 0)
     238           0 :                 dquot_free_space(inode, diff);
     239             :         else
     240           0 :                 err = dquot_alloc_space(inode, -1 * diff);
     241             : 
     242           0 :         if (err < 0) {
     243           0 : revert:
     244             :                 /* Revert all changes: */
     245           0 :                 inode_bl->i_blocks = blocks;
     246           0 :                 inode_bl->i_bytes = bytes;
     247           0 :                 swap_inode_data(inode, inode_bl);
     248           0 :                 ext4_mark_inode_dirty(handle, inode);
     249           0 :                 ext4_mark_inode_dirty(handle, inode_bl);
     250             :         }
     251             : 
     252           0 : err_out1:
     253           0 :         ext4_journal_stop(handle);
     254           0 :         ext4_fc_stop_ineligible(sb);
     255           0 :         ext4_double_up_write_data_sem(inode, inode_bl);
     256             : 
     257           0 : err_out:
     258           0 :         up_write(&EXT4_I(inode)->i_mmap_sem);
     259           0 : journal_err_out:
     260           0 :         unlock_two_nondirectories(inode, inode_bl);
     261           0 :         iput(inode_bl);
     262           0 :         return err;
     263             : }
     264             : 
     265             : #ifdef CONFIG_FS_ENCRYPTION
     266             : static int uuid_is_zero(__u8 u[16])
     267             : {
     268             :         int     i;
     269             : 
     270             :         for (i = 0; i < 16; i++)
     271             :                 if (u[i])
     272             :                         return 0;
     273             :         return 1;
     274             : }
     275             : #endif
     276             : 
     277             : /*
     278             :  * If immutable is set and we are not clearing it, we're not allowed to change
     279             :  * anything else in the inode.  Don't error out if we're only trying to set
     280             :  * immutable on an immutable file.
     281             :  */
     282           0 : static int ext4_ioctl_check_immutable(struct inode *inode, __u32 new_projid,
     283             :                                       unsigned int flags)
     284             : {
     285           0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     286           0 :         unsigned int oldflags = ei->i_flags;
     287             : 
     288           0 :         if (!(oldflags & EXT4_IMMUTABLE_FL) || !(flags & EXT4_IMMUTABLE_FL))
     289             :                 return 0;
     290             : 
     291           0 :         if ((oldflags & ~EXT4_IMMUTABLE_FL) != (flags & ~EXT4_IMMUTABLE_FL))
     292             :                 return -EPERM;
     293           0 :         if (ext4_has_feature_project(inode->i_sb) &&
     294           0 :             __kprojid_val(ei->i_projid) != new_projid)
     295           0 :                 return -EPERM;
     296             : 
     297             :         return 0;
     298             : }
     299             : 
     300           0 : static void ext4_dax_dontcache(struct inode *inode, unsigned int flags)
     301             : {
     302           0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     303             : 
     304           0 :         if (S_ISDIR(inode->i_mode))
     305             :                 return;
     306             : 
     307           0 :         if (test_opt2(inode->i_sb, DAX_NEVER) ||
     308           0 :             test_opt(inode->i_sb, DAX_ALWAYS))
     309             :                 return;
     310             : 
     311           0 :         if ((ei->i_flags ^ flags) & EXT4_DAX_FL)
     312           0 :                 d_mark_dontcache(inode);
     313             : }
     314             : 
     315           0 : static bool dax_compatible(struct inode *inode, unsigned int oldflags,
     316             :                            unsigned int flags)
     317             : {
     318           0 :         if (flags & EXT4_DAX_FL) {
     319           0 :                 if ((oldflags & EXT4_DAX_MUT_EXCL) ||
     320           0 :                      ext4_test_inode_state(inode,
     321             :                                           EXT4_STATE_VERITY_IN_PROGRESS)) {
     322           0 :                         return false;
     323             :                 }
     324             :         }
     325             : 
     326           0 :         if ((flags & EXT4_DAX_MUT_EXCL) && (oldflags & EXT4_DAX_FL))
     327           0 :                         return false;
     328             : 
     329             :         return true;
     330             : }
     331             : 
     332           0 : static int ext4_ioctl_setflags(struct inode *inode,
     333             :                                unsigned int flags)
     334             : {
     335           0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     336           0 :         handle_t *handle = NULL;
     337           0 :         int err = -EPERM, migrate = 0;
     338           0 :         struct ext4_iloc iloc;
     339           0 :         unsigned int oldflags, mask, i;
     340           0 :         struct super_block *sb = inode->i_sb;
     341             : 
     342             :         /* Is it quota file? Do not allow user to mess with it */
     343           0 :         if (ext4_is_quota_file(inode))
     344           0 :                 goto flags_out;
     345             : 
     346           0 :         oldflags = ei->i_flags;
     347             : 
     348           0 :         err = vfs_ioc_setflags_prepare(inode, oldflags, flags);
     349           0 :         if (err)
     350           0 :                 goto flags_out;
     351             : 
     352             :         /*
     353             :          * The JOURNAL_DATA flag can only be changed by
     354             :          * the relevant capability.
     355             :          */
     356           0 :         if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
     357           0 :                 if (!capable(CAP_SYS_RESOURCE))
     358           0 :                         goto flags_out;
     359             :         }
     360             : 
     361           0 :         if (!dax_compatible(inode, oldflags, flags)) {
     362           0 :                 err = -EOPNOTSUPP;
     363           0 :                 goto flags_out;
     364             :         }
     365             : 
     366           0 :         if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
     367           0 :                 migrate = 1;
     368             : 
     369           0 :         if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) {
     370           0 :                 if (!ext4_has_feature_casefold(sb)) {
     371           0 :                         err = -EOPNOTSUPP;
     372           0 :                         goto flags_out;
     373             :                 }
     374             : 
     375           0 :                 if (!S_ISDIR(inode->i_mode)) {
     376           0 :                         err = -ENOTDIR;
     377           0 :                         goto flags_out;
     378             :                 }
     379             : 
     380           0 :                 if (!ext4_empty_dir(inode)) {
     381           0 :                         err = -ENOTEMPTY;
     382           0 :                         goto flags_out;
     383             :                 }
     384             :         }
     385             : 
     386             :         /*
     387             :          * Wait for all pending directio and then flush all the dirty pages
     388             :          * for this file.  The flush marks all the pages readonly, so any
     389             :          * subsequent attempt to write to the file (particularly mmap pages)
     390             :          * will come through the filesystem and fail.
     391             :          */
     392           0 :         if (S_ISREG(inode->i_mode) && !IS_IMMUTABLE(inode) &&
     393           0 :             (flags & EXT4_IMMUTABLE_FL)) {
     394           0 :                 inode_dio_wait(inode);
     395           0 :                 err = filemap_write_and_wait(inode->i_mapping);
     396           0 :                 if (err)
     397           0 :                         goto flags_out;
     398             :         }
     399             : 
     400           0 :         handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
     401           0 :         if (IS_ERR(handle)) {
     402           0 :                 err = PTR_ERR(handle);
     403           0 :                 goto flags_out;
     404             :         }
     405           0 :         if (IS_SYNC(inode))
     406           0 :                 ext4_handle_sync(handle);
     407           0 :         err = ext4_reserve_inode_write(handle, inode, &iloc);
     408           0 :         if (err)
     409           0 :                 goto flags_err;
     410             : 
     411           0 :         ext4_dax_dontcache(inode, flags);
     412             : 
     413           0 :         for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
     414           0 :                 if (!(mask & EXT4_FL_USER_MODIFIABLE))
     415           0 :                         continue;
     416             :                 /* These flags get special treatment later */
     417           0 :                 if (mask == EXT4_JOURNAL_DATA_FL || mask == EXT4_EXTENTS_FL)
     418           0 :                         continue;
     419           0 :                 if (mask & flags)
     420           0 :                         ext4_set_inode_flag(inode, i);
     421             :                 else
     422           0 :                         ext4_clear_inode_flag(inode, i);
     423             :         }
     424             : 
     425           0 :         ext4_set_inode_flags(inode, false);
     426             : 
     427           0 :         inode->i_ctime = current_time(inode);
     428             : 
     429           0 :         err = ext4_mark_iloc_dirty(handle, inode, &iloc);
     430           0 : flags_err:
     431           0 :         ext4_journal_stop(handle);
     432           0 :         if (err)
     433           0 :                 goto flags_out;
     434             : 
     435           0 :         if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
     436             :                 /*
     437             :                  * Changes to the journaling mode can cause unsafe changes to
     438             :                  * S_DAX if the inode is DAX
     439             :                  */
     440           0 :                 if (IS_DAX(inode)) {
     441             :                         err = -EBUSY;
     442             :                         goto flags_out;
     443             :                 }
     444             : 
     445           0 :                 err = ext4_change_inode_journal_flag(inode,
     446           0 :                                                      flags & EXT4_JOURNAL_DATA_FL);
     447           0 :                 if (err)
     448           0 :                         goto flags_out;
     449             :         }
     450           0 :         if (migrate) {
     451           0 :                 if (flags & EXT4_EXTENTS_FL)
     452           0 :                         err = ext4_ext_migrate(inode);
     453             :                 else
     454           0 :                         err = ext4_ind_migrate(inode);
     455             :         }
     456             : 
     457           0 : flags_out:
     458           0 :         return err;
     459             : }
     460             : 
     461             : #ifdef CONFIG_QUOTA
     462             : static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
     463             : {
     464             :         struct inode *inode = file_inode(filp);
     465             :         struct super_block *sb = inode->i_sb;
     466             :         struct ext4_inode_info *ei = EXT4_I(inode);
     467             :         int err, rc;
     468             :         handle_t *handle;
     469             :         kprojid_t kprojid;
     470             :         struct ext4_iloc iloc;
     471             :         struct ext4_inode *raw_inode;
     472             :         struct dquot *transfer_to[MAXQUOTAS] = { };
     473             : 
     474             :         if (!ext4_has_feature_project(sb)) {
     475             :                 if (projid != EXT4_DEF_PROJID)
     476             :                         return -EOPNOTSUPP;
     477             :                 else
     478             :                         return 0;
     479             :         }
     480             : 
     481             :         if (EXT4_INODE_SIZE(sb) <= EXT4_GOOD_OLD_INODE_SIZE)
     482             :                 return -EOPNOTSUPP;
     483             : 
     484             :         kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
     485             : 
     486             :         if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
     487             :                 return 0;
     488             : 
     489             :         err = -EPERM;
     490             :         /* Is it quota file? Do not allow user to mess with it */
     491             :         if (ext4_is_quota_file(inode))
     492             :                 return err;
     493             : 
     494             :         err = ext4_get_inode_loc(inode, &iloc);
     495             :         if (err)
     496             :                 return err;
     497             : 
     498             :         raw_inode = ext4_raw_inode(&iloc);
     499             :         if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
     500             :                 err = ext4_expand_extra_isize(inode,
     501             :                                               EXT4_SB(sb)->s_want_extra_isize,
     502             :                                               &iloc);
     503             :                 if (err)
     504             :                         return err;
     505             :         } else {
     506             :                 brelse(iloc.bh);
     507             :         }
     508             : 
     509             :         err = dquot_initialize(inode);
     510             :         if (err)
     511             :                 return err;
     512             : 
     513             :         handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
     514             :                 EXT4_QUOTA_INIT_BLOCKS(sb) +
     515             :                 EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
     516             :         if (IS_ERR(handle))
     517             :                 return PTR_ERR(handle);
     518             : 
     519             :         err = ext4_reserve_inode_write(handle, inode, &iloc);
     520             :         if (err)
     521             :                 goto out_stop;
     522             : 
     523             :         transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
     524             :         if (!IS_ERR(transfer_to[PRJQUOTA])) {
     525             : 
     526             :                 /* __dquot_transfer() calls back ext4_get_inode_usage() which
     527             :                  * counts xattr inode references.
     528             :                  */
     529             :                 down_read(&EXT4_I(inode)->xattr_sem);
     530             :                 err = __dquot_transfer(inode, transfer_to);
     531             :                 up_read(&EXT4_I(inode)->xattr_sem);
     532             :                 dqput(transfer_to[PRJQUOTA]);
     533             :                 if (err)
     534             :                         goto out_dirty;
     535             :         }
     536             : 
     537             :         EXT4_I(inode)->i_projid = kprojid;
     538             :         inode->i_ctime = current_time(inode);
     539             : out_dirty:
     540             :         rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
     541             :         if (!err)
     542             :                 err = rc;
     543             : out_stop:
     544             :         ext4_journal_stop(handle);
     545             :         return err;
     546             : }
     547             : #else
     548           0 : static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
     549             : {
     550           0 :         if (projid != EXT4_DEF_PROJID)
     551           0 :                 return -EOPNOTSUPP;
     552             :         return 0;
     553             : }
     554             : #endif
     555             : 
     556             : /* Transfer internal flags to xflags */
     557           0 : static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
     558             : {
     559           0 :         __u32 xflags = 0;
     560             : 
     561           0 :         if (iflags & EXT4_SYNC_FL)
     562           0 :                 xflags |= FS_XFLAG_SYNC;
     563           0 :         if (iflags & EXT4_IMMUTABLE_FL)
     564           0 :                 xflags |= FS_XFLAG_IMMUTABLE;
     565           0 :         if (iflags & EXT4_APPEND_FL)
     566           0 :                 xflags |= FS_XFLAG_APPEND;
     567           0 :         if (iflags & EXT4_NODUMP_FL)
     568           0 :                 xflags |= FS_XFLAG_NODUMP;
     569           0 :         if (iflags & EXT4_NOATIME_FL)
     570           0 :                 xflags |= FS_XFLAG_NOATIME;
     571           0 :         if (iflags & EXT4_PROJINHERIT_FL)
     572           0 :                 xflags |= FS_XFLAG_PROJINHERIT;
     573           0 :         if (iflags & EXT4_DAX_FL)
     574           0 :                 xflags |= FS_XFLAG_DAX;
     575           0 :         return xflags;
     576             : }
     577             : 
     578             : #define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \
     579             :                                   FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \
     580             :                                   FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \
     581             :                                   FS_XFLAG_DAX)
     582             : 
     583             : /* Transfer xflags flags to internal */
     584           0 : static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
     585             : {
     586           0 :         unsigned long iflags = 0;
     587             : 
     588           0 :         if (xflags & FS_XFLAG_SYNC)
     589           0 :                 iflags |= EXT4_SYNC_FL;
     590           0 :         if (xflags & FS_XFLAG_IMMUTABLE)
     591           0 :                 iflags |= EXT4_IMMUTABLE_FL;
     592           0 :         if (xflags & FS_XFLAG_APPEND)
     593           0 :                 iflags |= EXT4_APPEND_FL;
     594           0 :         if (xflags & FS_XFLAG_NODUMP)
     595           0 :                 iflags |= EXT4_NODUMP_FL;
     596           0 :         if (xflags & FS_XFLAG_NOATIME)
     597           0 :                 iflags |= EXT4_NOATIME_FL;
     598           0 :         if (xflags & FS_XFLAG_PROJINHERIT)
     599           0 :                 iflags |= EXT4_PROJINHERIT_FL;
     600           0 :         if (xflags & FS_XFLAG_DAX)
     601           0 :                 iflags |= EXT4_DAX_FL;
     602             : 
     603           0 :         return iflags;
     604             : }
     605             : 
     606           0 : static int ext4_shutdown(struct super_block *sb, unsigned long arg)
     607             : {
     608           0 :         struct ext4_sb_info *sbi = EXT4_SB(sb);
     609           0 :         __u32 flags;
     610             : 
     611           0 :         if (!capable(CAP_SYS_ADMIN))
     612             :                 return -EPERM;
     613             : 
     614           0 :         if (get_user(flags, (__u32 __user *)arg))
     615             :                 return -EFAULT;
     616             : 
     617           0 :         if (flags > EXT4_GOING_FLAGS_NOLOGFLUSH)
     618             :                 return -EINVAL;
     619             : 
     620           0 :         if (ext4_forced_shutdown(sbi))
     621             :                 return 0;
     622             : 
     623           0 :         ext4_msg(sb, KERN_ALERT, "shut down requested (%d)", flags);
     624           0 :         trace_ext4_shutdown(sb, flags);
     625             : 
     626           0 :         switch (flags) {
     627           0 :         case EXT4_GOING_FLAGS_DEFAULT:
     628           0 :                 freeze_bdev(sb->s_bdev);
     629           0 :                 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
     630           0 :                 thaw_bdev(sb->s_bdev);
     631           0 :                 break;
     632           0 :         case EXT4_GOING_FLAGS_LOGFLUSH:
     633           0 :                 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
     634           0 :                 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) {
     635           0 :                         (void) ext4_force_commit(sb);
     636           0 :                         jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
     637             :                 }
     638             :                 break;
     639           0 :         case EXT4_GOING_FLAGS_NOLOGFLUSH:
     640           0 :                 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
     641           0 :                 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal))
     642           0 :                         jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
     643             :                 break;
     644             :         default:
     645             :                 return -EINVAL;
     646             :         }
     647           0 :         clear_opt(sb, DISCARD);
     648           0 :         return 0;
     649             : }
     650             : 
     651             : struct getfsmap_info {
     652             :         struct super_block      *gi_sb;
     653             :         struct fsmap_head __user *gi_data;
     654             :         unsigned int            gi_idx;
     655             :         __u32                   gi_last_flags;
     656             : };
     657             : 
     658           0 : static int ext4_getfsmap_format(struct ext4_fsmap *xfm, void *priv)
     659             : {
     660           0 :         struct getfsmap_info *info = priv;
     661           0 :         struct fsmap fm;
     662             : 
     663           0 :         trace_ext4_getfsmap_mapping(info->gi_sb, xfm);
     664             : 
     665           0 :         info->gi_last_flags = xfm->fmr_flags;
     666           0 :         ext4_fsmap_from_internal(info->gi_sb, &fm, xfm);
     667           0 :         if (copy_to_user(&info->gi_data->fmh_recs[info->gi_idx++], &fm,
     668             :                         sizeof(struct fsmap)))
     669           0 :                 return -EFAULT;
     670             : 
     671             :         return 0;
     672             : }
     673             : 
     674           0 : static int ext4_ioc_getfsmap(struct super_block *sb,
     675             :                              struct fsmap_head __user *arg)
     676             : {
     677           0 :         struct getfsmap_info info = { NULL };
     678           0 :         struct ext4_fsmap_head xhead = {0};
     679           0 :         struct fsmap_head head;
     680           0 :         bool aborted = false;
     681           0 :         int error;
     682             : 
     683           0 :         if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
     684             :                 return -EFAULT;
     685           0 :         if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
     686           0 :             memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
     687           0 :                        sizeof(head.fmh_keys[0].fmr_reserved)) ||
     688           0 :             memchr_inv(head.fmh_keys[1].fmr_reserved, 0,
     689             :                        sizeof(head.fmh_keys[1].fmr_reserved)))
     690           0 :                 return -EINVAL;
     691             :         /*
     692             :          * ext4 doesn't report file extents at all, so the only valid
     693             :          * file offsets are the magic ones (all zeroes or all ones).
     694             :          */
     695           0 :         if (head.fmh_keys[0].fmr_offset ||
     696           0 :             (head.fmh_keys[1].fmr_offset != 0 &&
     697             :              head.fmh_keys[1].fmr_offset != -1ULL))
     698             :                 return -EINVAL;
     699             : 
     700           0 :         xhead.fmh_iflags = head.fmh_iflags;
     701           0 :         xhead.fmh_count = head.fmh_count;
     702           0 :         ext4_fsmap_to_internal(sb, &xhead.fmh_keys[0], &head.fmh_keys[0]);
     703           0 :         ext4_fsmap_to_internal(sb, &xhead.fmh_keys[1], &head.fmh_keys[1]);
     704             : 
     705           0 :         trace_ext4_getfsmap_low_key(sb, &xhead.fmh_keys[0]);
     706           0 :         trace_ext4_getfsmap_high_key(sb, &xhead.fmh_keys[1]);
     707             : 
     708           0 :         info.gi_sb = sb;
     709           0 :         info.gi_data = arg;
     710           0 :         error = ext4_getfsmap(sb, &xhead, ext4_getfsmap_format, &info);
     711           0 :         if (error == EXT4_QUERY_RANGE_ABORT) {
     712           0 :                 error = 0;
     713             :                 aborted = true;
     714           0 :         } else if (error)
     715             :                 return error;
     716             : 
     717             :         /* If we didn't abort, set the "last" flag in the last fmx */
     718           0 :         if (!aborted && info.gi_idx) {
     719           0 :                 info.gi_last_flags |= FMR_OF_LAST;
     720           0 :                 if (copy_to_user(&info.gi_data->fmh_recs[info.gi_idx - 1].fmr_flags,
     721             :                                  &info.gi_last_flags,
     722             :                                  sizeof(info.gi_last_flags)))
     723             :                         return -EFAULT;
     724             :         }
     725             : 
     726             :         /* copy back header */
     727           0 :         head.fmh_entries = xhead.fmh_entries;
     728           0 :         head.fmh_oflags = xhead.fmh_oflags;
     729           0 :         if (copy_to_user(arg, &head, sizeof(struct fsmap_head)))
     730           0 :                 return -EFAULT;
     731             : 
     732             :         return 0;
     733             : }
     734             : 
     735           0 : static long ext4_ioctl_group_add(struct file *file,
     736             :                                  struct ext4_new_group_data *input)
     737             : {
     738           0 :         struct super_block *sb = file_inode(file)->i_sb;
     739           0 :         int err, err2=0;
     740             : 
     741           0 :         err = ext4_resize_begin(sb);
     742           0 :         if (err)
     743           0 :                 return err;
     744             : 
     745           0 :         if (ext4_has_feature_bigalloc(sb)) {
     746           0 :                 ext4_msg(sb, KERN_ERR,
     747             :                          "Online resizing not supported with bigalloc");
     748           0 :                 err = -EOPNOTSUPP;
     749           0 :                 goto group_add_out;
     750             :         }
     751             : 
     752           0 :         err = mnt_want_write_file(file);
     753           0 :         if (err)
     754           0 :                 goto group_add_out;
     755             : 
     756           0 :         err = ext4_group_add(sb, input);
     757           0 :         if (EXT4_SB(sb)->s_journal) {
     758           0 :                 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
     759           0 :                 err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
     760           0 :                 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
     761             :         }
     762           0 :         if (err == 0)
     763           0 :                 err = err2;
     764           0 :         mnt_drop_write_file(file);
     765           0 :         if (!err && ext4_has_group_desc_csum(sb) &&
     766           0 :             test_opt(sb, INIT_INODE_TABLE))
     767           0 :                 err = ext4_register_li_request(sb, input->group);
     768           0 : group_add_out:
     769           0 :         ext4_resize_end(sb);
     770           0 :         return err;
     771             : }
     772             : 
     773           0 : static void ext4_fill_fsxattr(struct inode *inode, struct fsxattr *fa)
     774             : {
     775           0 :         struct ext4_inode_info *ei = EXT4_I(inode);
     776             : 
     777           0 :         simple_fill_fsxattr(fa, ext4_iflags_to_xflags(ei->i_flags &
     778             :                                                       EXT4_FL_USER_VISIBLE));
     779             : 
     780           0 :         if (ext4_has_feature_project(inode->i_sb))
     781           0 :                 fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid);
     782           0 : }
     783             : 
     784             : /* So that the fiemap access checks can't overflow on 32 bit machines. */
     785             : #define FIEMAP_MAX_EXTENTS      (UINT_MAX / sizeof(struct fiemap_extent))
     786             : 
     787           0 : static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg)
     788             : {
     789           0 :         struct fiemap fiemap;
     790           0 :         struct fiemap __user *ufiemap = (struct fiemap __user *) arg;
     791           0 :         struct fiemap_extent_info fieinfo = { 0, };
     792           0 :         struct inode *inode = file_inode(filp);
     793           0 :         int error;
     794             : 
     795           0 :         if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
     796             :                 return -EFAULT;
     797             : 
     798           0 :         if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
     799             :                 return -EINVAL;
     800             : 
     801           0 :         fieinfo.fi_flags = fiemap.fm_flags;
     802           0 :         fieinfo.fi_extents_max = fiemap.fm_extent_count;
     803           0 :         fieinfo.fi_extents_start = ufiemap->fm_extents;
     804             : 
     805           0 :         error = ext4_get_es_cache(inode, &fieinfo, fiemap.fm_start,
     806             :                         fiemap.fm_length);
     807           0 :         fiemap.fm_flags = fieinfo.fi_flags;
     808           0 :         fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
     809           0 :         if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
     810           0 :                 error = -EFAULT;
     811             : 
     812             :         return error;
     813             : }
     814             : 
     815          61 : static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
     816             : {
     817          61 :         struct inode *inode = file_inode(filp);
     818          61 :         struct super_block *sb = inode->i_sb;
     819          61 :         struct ext4_inode_info *ei = EXT4_I(inode);
     820          61 :         struct user_namespace *mnt_userns = file_mnt_user_ns(filp);
     821          61 :         unsigned int flags;
     822             : 
     823          61 :         ext4_debug("cmd = %u, arg = %lu\n", cmd, arg);
     824             : 
     825          61 :         switch (cmd) {
     826           0 :         case FS_IOC_GETFSMAP:
     827           0 :                 return ext4_ioc_getfsmap(sb, (void __user *)arg);
     828           0 :         case FS_IOC_GETFLAGS:
     829           0 :                 flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
     830           0 :                 if (S_ISREG(inode->i_mode))
     831           0 :                         flags &= ~EXT4_PROJINHERIT_FL;
     832           0 :                 return put_user(flags, (int __user *) arg);
     833           0 :         case FS_IOC_SETFLAGS: {
     834           0 :                 int err;
     835             : 
     836           0 :                 if (!inode_owner_or_capable(mnt_userns, inode))
     837             :                         return -EACCES;
     838             : 
     839           0 :                 if (get_user(flags, (int __user *) arg))
     840             :                         return -EFAULT;
     841             : 
     842           0 :                 if (flags & ~EXT4_FL_USER_VISIBLE)
     843             :                         return -EOPNOTSUPP;
     844             :                 /*
     845             :                  * chattr(1) grabs flags via GETFLAGS, modifies the result and
     846             :                  * passes that to SETFLAGS. So we cannot easily make SETFLAGS
     847             :                  * more restrictive than just silently masking off visible but
     848             :                  * not settable flags as we always did.
     849             :                  */
     850           0 :                 flags &= EXT4_FL_USER_MODIFIABLE;
     851           0 :                 if (ext4_mask_flags(inode->i_mode, flags) != flags)
     852             :                         return -EOPNOTSUPP;
     853             : 
     854           0 :                 err = mnt_want_write_file(filp);
     855           0 :                 if (err)
     856           0 :                         return err;
     857             : 
     858           0 :                 inode_lock(inode);
     859           0 :                 err = ext4_ioctl_check_immutable(inode,
     860             :                                 from_kprojid(&init_user_ns, ei->i_projid),
     861             :                                 flags);
     862           0 :                 if (!err)
     863           0 :                         err = ext4_ioctl_setflags(inode, flags);
     864           0 :                 inode_unlock(inode);
     865           0 :                 mnt_drop_write_file(filp);
     866           0 :                 return err;
     867             :         }
     868           0 :         case EXT4_IOC_GETVERSION:
     869             :         case EXT4_IOC_GETVERSION_OLD:
     870           0 :                 return put_user(inode->i_generation, (int __user *) arg);
     871           0 :         case EXT4_IOC_SETVERSION:
     872             :         case EXT4_IOC_SETVERSION_OLD: {
     873           0 :                 handle_t *handle;
     874           0 :                 struct ext4_iloc iloc;
     875           0 :                 __u32 generation;
     876           0 :                 int err;
     877             : 
     878           0 :                 if (!inode_owner_or_capable(mnt_userns, inode))
     879             :                         return -EPERM;
     880             : 
     881           0 :                 if (ext4_has_metadata_csum(inode->i_sb)) {
     882           0 :                         ext4_warning(sb, "Setting inode version is not "
     883             :                                      "supported with metadata_csum enabled.");
     884           0 :                         return -ENOTTY;
     885             :                 }
     886             : 
     887           0 :                 err = mnt_want_write_file(filp);
     888           0 :                 if (err)
     889           0 :                         return err;
     890           0 :                 if (get_user(generation, (int __user *) arg)) {
     891           0 :                         err = -EFAULT;
     892           0 :                         goto setversion_out;
     893             :                 }
     894             : 
     895           0 :                 inode_lock(inode);
     896           0 :                 handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
     897           0 :                 if (IS_ERR(handle)) {
     898           0 :                         err = PTR_ERR(handle);
     899           0 :                         goto unlock_out;
     900             :                 }
     901           0 :                 err = ext4_reserve_inode_write(handle, inode, &iloc);
     902           0 :                 if (err == 0) {
     903           0 :                         inode->i_ctime = current_time(inode);
     904           0 :                         inode->i_generation = generation;
     905           0 :                         err = ext4_mark_iloc_dirty(handle, inode, &iloc);
     906             :                 }
     907           0 :                 ext4_journal_stop(handle);
     908             : 
     909           0 : unlock_out:
     910           0 :                 inode_unlock(inode);
     911           0 : setversion_out:
     912           0 :                 mnt_drop_write_file(filp);
     913           0 :                 return err;
     914             :         }
     915           0 :         case EXT4_IOC_GROUP_EXTEND: {
     916           0 :                 ext4_fsblk_t n_blocks_count;
     917           0 :                 int err, err2=0;
     918             : 
     919           0 :                 err = ext4_resize_begin(sb);
     920           0 :                 if (err)
     921           0 :                         return err;
     922             : 
     923           0 :                 if (get_user(n_blocks_count, (__u32 __user *)arg)) {
     924           0 :                         err = -EFAULT;
     925           0 :                         goto group_extend_out;
     926             :                 }
     927             : 
     928           0 :                 if (ext4_has_feature_bigalloc(sb)) {
     929           0 :                         ext4_msg(sb, KERN_ERR,
     930             :                                  "Online resizing not supported with bigalloc");
     931           0 :                         err = -EOPNOTSUPP;
     932           0 :                         goto group_extend_out;
     933             :                 }
     934             : 
     935           0 :                 err = mnt_want_write_file(filp);
     936           0 :                 if (err)
     937           0 :                         goto group_extend_out;
     938             : 
     939           0 :                 err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
     940           0 :                 if (EXT4_SB(sb)->s_journal) {
     941           0 :                         jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
     942           0 :                         err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
     943           0 :                         jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
     944             :                 }
     945           0 :                 if (err == 0)
     946           0 :                         err = err2;
     947           0 :                 mnt_drop_write_file(filp);
     948           0 : group_extend_out:
     949           0 :                 ext4_resize_end(sb);
     950           0 :                 return err;
     951             :         }
     952             : 
     953           0 :         case EXT4_IOC_MOVE_EXT: {
     954           0 :                 struct move_extent me;
     955           0 :                 struct fd donor;
     956           0 :                 int err;
     957             : 
     958           0 :                 if (!(filp->f_mode & FMODE_READ) ||
     959             :                     !(filp->f_mode & FMODE_WRITE))
     960             :                         return -EBADF;
     961             : 
     962           0 :                 if (copy_from_user(&me,
     963             :                         (struct move_extent __user *)arg, sizeof(me)))
     964             :                         return -EFAULT;
     965           0 :                 me.moved_len = 0;
     966             : 
     967           0 :                 donor = fdget(me.donor_fd);
     968           0 :                 if (!donor.file)
     969             :                         return -EBADF;
     970             : 
     971           0 :                 if (!(donor.file->f_mode & FMODE_WRITE)) {
     972           0 :                         err = -EBADF;
     973           0 :                         goto mext_out;
     974             :                 }
     975             : 
     976           0 :                 if (ext4_has_feature_bigalloc(sb)) {
     977           0 :                         ext4_msg(sb, KERN_ERR,
     978             :                                  "Online defrag not supported with bigalloc");
     979           0 :                         err = -EOPNOTSUPP;
     980           0 :                         goto mext_out;
     981           0 :                 } else if (IS_DAX(inode)) {
     982             :                         ext4_msg(sb, KERN_ERR,
     983             :                                  "Online defrag not supported with DAX");
     984             :                         err = -EOPNOTSUPP;
     985             :                         goto mext_out;
     986             :                 }
     987             : 
     988           0 :                 err = mnt_want_write_file(filp);
     989           0 :                 if (err)
     990           0 :                         goto mext_out;
     991             : 
     992           0 :                 err = ext4_move_extents(filp, donor.file, me.orig_start,
     993             :                                         me.donor_start, me.len, &me.moved_len);
     994           0 :                 mnt_drop_write_file(filp);
     995             : 
     996           0 :                 if (copy_to_user((struct move_extent __user *)arg,
     997             :                                  &me, sizeof(me)))
     998           0 :                         err = -EFAULT;
     999           0 : mext_out:
    1000           0 :                 fdput(donor);
    1001           0 :                 return err;
    1002             :         }
    1003             : 
    1004           0 :         case EXT4_IOC_GROUP_ADD: {
    1005           0 :                 struct ext4_new_group_data input;
    1006             : 
    1007           0 :                 if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
    1008             :                                 sizeof(input)))
    1009             :                         return -EFAULT;
    1010             : 
    1011           0 :                 return ext4_ioctl_group_add(filp, &input);
    1012             :         }
    1013             : 
    1014           0 :         case EXT4_IOC_MIGRATE:
    1015             :         {
    1016           0 :                 int err;
    1017           0 :                 if (!inode_owner_or_capable(mnt_userns, inode))
    1018             :                         return -EACCES;
    1019             : 
    1020           0 :                 err = mnt_want_write_file(filp);
    1021           0 :                 if (err)
    1022           0 :                         return err;
    1023             :                 /*
    1024             :                  * inode_mutex prevent write and truncate on the file.
    1025             :                  * Read still goes through. We take i_data_sem in
    1026             :                  * ext4_ext_swap_inode_data before we switch the
    1027             :                  * inode format to prevent read.
    1028             :                  */
    1029           0 :                 inode_lock((inode));
    1030           0 :                 err = ext4_ext_migrate(inode);
    1031           0 :                 inode_unlock((inode));
    1032           0 :                 mnt_drop_write_file(filp);
    1033           0 :                 return err;
    1034             :         }
    1035             : 
    1036           0 :         case EXT4_IOC_ALLOC_DA_BLKS:
    1037             :         {
    1038           0 :                 int err;
    1039           0 :                 if (!inode_owner_or_capable(mnt_userns, inode))
    1040             :                         return -EACCES;
    1041             : 
    1042           0 :                 err = mnt_want_write_file(filp);
    1043           0 :                 if (err)
    1044           0 :                         return err;
    1045           0 :                 err = ext4_alloc_da_blocks(inode);
    1046           0 :                 mnt_drop_write_file(filp);
    1047           0 :                 return err;
    1048             :         }
    1049             : 
    1050           0 :         case EXT4_IOC_SWAP_BOOT:
    1051             :         {
    1052           0 :                 int err;
    1053           0 :                 if (!(filp->f_mode & FMODE_WRITE))
    1054             :                         return -EBADF;
    1055           0 :                 err = mnt_want_write_file(filp);
    1056           0 :                 if (err)
    1057           0 :                         return err;
    1058           0 :                 err = swap_inode_boot_loader(sb, mnt_userns, inode);
    1059           0 :                 mnt_drop_write_file(filp);
    1060           0 :                 return err;
    1061             :         }
    1062             : 
    1063           0 :         case EXT4_IOC_RESIZE_FS: {
    1064           0 :                 ext4_fsblk_t n_blocks_count;
    1065           0 :                 int err = 0, err2 = 0;
    1066           0 :                 ext4_group_t o_group = EXT4_SB(sb)->s_groups_count;
    1067             : 
    1068           0 :                 if (copy_from_user(&n_blocks_count, (__u64 __user *)arg,
    1069             :                                    sizeof(__u64))) {
    1070             :                         return -EFAULT;
    1071             :                 }
    1072             : 
    1073           0 :                 err = ext4_resize_begin(sb);
    1074           0 :                 if (err)
    1075           0 :                         return err;
    1076             : 
    1077           0 :                 err = mnt_want_write_file(filp);
    1078           0 :                 if (err)
    1079           0 :                         goto resizefs_out;
    1080             : 
    1081           0 :                 err = ext4_resize_fs(sb, n_blocks_count);
    1082           0 :                 if (EXT4_SB(sb)->s_journal) {
    1083           0 :                         ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_RESIZE);
    1084           0 :                         jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
    1085           0 :                         err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
    1086           0 :                         jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
    1087             :                 }
    1088           0 :                 if (err == 0)
    1089           0 :                         err = err2;
    1090           0 :                 mnt_drop_write_file(filp);
    1091           0 :                 if (!err && (o_group < EXT4_SB(sb)->s_groups_count) &&
    1092           0 :                     ext4_has_group_desc_csum(sb) &&
    1093           0 :                     test_opt(sb, INIT_INODE_TABLE))
    1094           0 :                         err = ext4_register_li_request(sb, o_group);
    1095             : 
    1096           0 : resizefs_out:
    1097           0 :                 ext4_resize_end(sb);
    1098           0 :                 return err;
    1099             :         }
    1100             : 
    1101           0 :         case FITRIM:
    1102             :         {
    1103           0 :                 struct request_queue *q = bdev_get_queue(sb->s_bdev);
    1104           0 :                 struct fstrim_range range;
    1105           0 :                 int ret = 0;
    1106             : 
    1107           0 :                 if (!capable(CAP_SYS_ADMIN))
    1108             :                         return -EPERM;
    1109             : 
    1110           0 :                 if (!blk_queue_discard(q))
    1111             :                         return -EOPNOTSUPP;
    1112             : 
    1113             :                 /*
    1114             :                  * We haven't replayed the journal, so we cannot use our
    1115             :                  * block-bitmap-guided storage zapping commands.
    1116             :                  */
    1117           0 :                 if (test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb))
    1118             :                         return -EROFS;
    1119             : 
    1120           0 :                 if (copy_from_user(&range, (struct fstrim_range __user *)arg,
    1121             :                     sizeof(range)))
    1122             :                         return -EFAULT;
    1123             : 
    1124           0 :                 range.minlen = max((unsigned int)range.minlen,
    1125             :                                    q->limits.discard_granularity);
    1126           0 :                 ret = ext4_trim_fs(sb, &range);
    1127           0 :                 if (ret < 0)
    1128           0 :                         return ret;
    1129             : 
    1130           0 :                 if (copy_to_user((struct fstrim_range __user *)arg, &range,
    1131             :                     sizeof(range)))
    1132           0 :                         return -EFAULT;
    1133             : 
    1134             :                 return 0;
    1135             :         }
    1136           0 :         case EXT4_IOC_PRECACHE_EXTENTS:
    1137           0 :                 return ext4_ext_precache(inode);
    1138             : 
    1139             :         case FS_IOC_SET_ENCRYPTION_POLICY:
    1140           0 :                 if (!ext4_has_feature_encrypt(sb))
    1141             :                         return -EOPNOTSUPP;
    1142          61 :                 return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
    1143             : 
    1144             :         case FS_IOC_GET_ENCRYPTION_PWSALT: {
    1145             : #ifdef CONFIG_FS_ENCRYPTION
    1146             :                 int err, err2;
    1147             :                 struct ext4_sb_info *sbi = EXT4_SB(sb);
    1148             :                 handle_t *handle;
    1149             : 
    1150             :                 if (!ext4_has_feature_encrypt(sb))
    1151             :                         return -EOPNOTSUPP;
    1152             :                 if (uuid_is_zero(sbi->s_es->s_encrypt_pw_salt)) {
    1153             :                         err = mnt_want_write_file(filp);
    1154             :                         if (err)
    1155             :                                 return err;
    1156             :                         handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1);
    1157             :                         if (IS_ERR(handle)) {
    1158             :                                 err = PTR_ERR(handle);
    1159             :                                 goto pwsalt_err_exit;
    1160             :                         }
    1161             :                         err = ext4_journal_get_write_access(handle, sbi->s_sbh);
    1162             :                         if (err)
    1163             :                                 goto pwsalt_err_journal;
    1164             :                         lock_buffer(sbi->s_sbh);
    1165             :                         generate_random_uuid(sbi->s_es->s_encrypt_pw_salt);
    1166             :                         ext4_superblock_csum_set(sb);
    1167             :                         unlock_buffer(sbi->s_sbh);
    1168             :                         err = ext4_handle_dirty_metadata(handle, NULL,
    1169             :                                                          sbi->s_sbh);
    1170             :                 pwsalt_err_journal:
    1171             :                         err2 = ext4_journal_stop(handle);
    1172             :                         if (err2 && !err)
    1173             :                                 err = err2;
    1174             :                 pwsalt_err_exit:
    1175             :                         mnt_drop_write_file(filp);
    1176             :                         if (err)
    1177             :                                 return err;
    1178             :                 }
    1179             :                 if (copy_to_user((void __user *) arg,
    1180             :                                  sbi->s_es->s_encrypt_pw_salt, 16))
    1181             :                         return -EFAULT;
    1182             :                 return 0;
    1183             : #else
    1184             :                 return -EOPNOTSUPP;
    1185             : #endif
    1186             :         }
    1187             :         case FS_IOC_GET_ENCRYPTION_POLICY:
    1188           0 :                 if (!ext4_has_feature_encrypt(sb))
    1189             :                         return -EOPNOTSUPP;
    1190          61 :                 return fscrypt_ioctl_get_policy(filp, (void __user *)arg);
    1191             : 
    1192             :         case FS_IOC_GET_ENCRYPTION_POLICY_EX:
    1193           0 :                 if (!ext4_has_feature_encrypt(sb))
    1194             :                         return -EOPNOTSUPP;
    1195          61 :                 return fscrypt_ioctl_get_policy_ex(filp, (void __user *)arg);
    1196             : 
    1197             :         case FS_IOC_ADD_ENCRYPTION_KEY:
    1198           0 :                 if (!ext4_has_feature_encrypt(sb))
    1199             :                         return -EOPNOTSUPP;
    1200          61 :                 return fscrypt_ioctl_add_key(filp, (void __user *)arg);
    1201             : 
    1202             :         case FS_IOC_REMOVE_ENCRYPTION_KEY:
    1203           0 :                 if (!ext4_has_feature_encrypt(sb))
    1204             :                         return -EOPNOTSUPP;
    1205          61 :                 return fscrypt_ioctl_remove_key(filp, (void __user *)arg);
    1206             : 
    1207             :         case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS:
    1208           0 :                 if (!ext4_has_feature_encrypt(sb))
    1209             :                         return -EOPNOTSUPP;
    1210          61 :                 return fscrypt_ioctl_remove_key_all_users(filp,
    1211             :                                                           (void __user *)arg);
    1212             :         case FS_IOC_GET_ENCRYPTION_KEY_STATUS:
    1213           0 :                 if (!ext4_has_feature_encrypt(sb))
    1214             :                         return -EOPNOTSUPP;
    1215          61 :                 return fscrypt_ioctl_get_key_status(filp, (void __user *)arg);
    1216             : 
    1217             :         case FS_IOC_GET_ENCRYPTION_NONCE:
    1218           0 :                 if (!ext4_has_feature_encrypt(sb))
    1219             :                         return -EOPNOTSUPP;
    1220          61 :                 return fscrypt_ioctl_get_nonce(filp, (void __user *)arg);
    1221             : 
    1222           0 :         case EXT4_IOC_CLEAR_ES_CACHE:
    1223             :         {
    1224           0 :                 if (!inode_owner_or_capable(mnt_userns, inode))
    1225             :                         return -EACCES;
    1226           0 :                 ext4_clear_inode_es(inode);
    1227           0 :                 return 0;
    1228             :         }
    1229             : 
    1230           0 :         case EXT4_IOC_GETSTATE:
    1231             :         {
    1232           0 :                 __u32   state = 0;
    1233             : 
    1234           0 :                 if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED))
    1235           0 :                         state |= EXT4_STATE_FLAG_EXT_PRECACHED;
    1236           0 :                 if (ext4_test_inode_state(inode, EXT4_STATE_NEW))
    1237           0 :                         state |= EXT4_STATE_FLAG_NEW;
    1238           0 :                 if (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY))
    1239           0 :                         state |= EXT4_STATE_FLAG_NEWENTRY;
    1240           0 :                 if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE))
    1241           0 :                         state |= EXT4_STATE_FLAG_DA_ALLOC_CLOSE;
    1242             : 
    1243           0 :                 return put_user(state, (__u32 __user *) arg);
    1244             :         }
    1245             : 
    1246           0 :         case EXT4_IOC_GET_ES_CACHE:
    1247           0 :                 return ext4_ioctl_get_es_cache(filp, arg);
    1248             : 
    1249           0 :         case FS_IOC_FSGETXATTR:
    1250             :         {
    1251           0 :                 struct fsxattr fa;
    1252             : 
    1253           0 :                 ext4_fill_fsxattr(inode, &fa);
    1254             : 
    1255           0 :                 if (copy_to_user((struct fsxattr __user *)arg,
    1256             :                                  &fa, sizeof(fa)))
    1257           0 :                         return -EFAULT;
    1258             :                 return 0;
    1259             :         }
    1260           0 :         case FS_IOC_FSSETXATTR:
    1261             :         {
    1262           0 :                 struct fsxattr fa, old_fa;
    1263           0 :                 int err;
    1264             : 
    1265           0 :                 if (copy_from_user(&fa, (struct fsxattr __user *)arg,
    1266             :                                    sizeof(fa)))
    1267             :                         return -EFAULT;
    1268             : 
    1269             :                 /* Make sure caller has proper permission */
    1270           0 :                 if (!inode_owner_or_capable(mnt_userns, inode))
    1271             :                         return -EACCES;
    1272             : 
    1273           0 :                 if (fa.fsx_xflags & ~EXT4_SUPPORTED_FS_XFLAGS)
    1274             :                         return -EOPNOTSUPP;
    1275             : 
    1276           0 :                 flags = ext4_xflags_to_iflags(fa.fsx_xflags);
    1277           0 :                 if (ext4_mask_flags(inode->i_mode, flags) != flags)
    1278             :                         return -EOPNOTSUPP;
    1279             : 
    1280           0 :                 err = mnt_want_write_file(filp);
    1281           0 :                 if (err)
    1282           0 :                         return err;
    1283             : 
    1284           0 :                 inode_lock(inode);
    1285           0 :                 ext4_fill_fsxattr(inode, &old_fa);
    1286           0 :                 err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa);
    1287           0 :                 if (err)
    1288           0 :                         goto out;
    1289           0 :                 flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
    1290           0 :                          (flags & EXT4_FL_XFLAG_VISIBLE);
    1291           0 :                 err = ext4_ioctl_check_immutable(inode, fa.fsx_projid, flags);
    1292           0 :                 if (err)
    1293           0 :                         goto out;
    1294           0 :                 err = ext4_ioctl_setflags(inode, flags);
    1295           0 :                 if (err)
    1296           0 :                         goto out;
    1297           0 :                 err = ext4_ioctl_setproject(filp, fa.fsx_projid);
    1298           0 : out:
    1299           0 :                 inode_unlock(inode);
    1300           0 :                 mnt_drop_write_file(filp);
    1301           0 :                 return err;
    1302             :         }
    1303           0 :         case EXT4_IOC_SHUTDOWN:
    1304           0 :                 return ext4_shutdown(sb, arg);
    1305             : 
    1306             :         case FS_IOC_ENABLE_VERITY:
    1307           0 :                 if (!ext4_has_feature_verity(sb))
    1308             :                         return -EOPNOTSUPP;
    1309          61 :                 return fsverity_ioctl_enable(filp, (const void __user *)arg);
    1310             : 
    1311             :         case FS_IOC_MEASURE_VERITY:
    1312           0 :                 if (!ext4_has_feature_verity(sb))
    1313             :                         return -EOPNOTSUPP;
    1314          61 :                 return fsverity_ioctl_measure(filp, (void __user *)arg);
    1315             : 
    1316             :         case FS_IOC_READ_VERITY_METADATA:
    1317           0 :                 if (!ext4_has_feature_verity(sb))
    1318             :                         return -EOPNOTSUPP;
    1319          61 :                 return fsverity_ioctl_read_metadata(filp,
    1320             :                                                     (const void __user *)arg);
    1321             : 
    1322          61 :         default:
    1323          61 :                 return -ENOTTY;
    1324             :         }
    1325             : }
    1326             : 
    1327          61 : long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
    1328             : {
    1329          61 :         long ret;
    1330             : 
    1331          61 :         ext4_fc_start_update(file_inode(filp));
    1332          61 :         ret = __ext4_ioctl(filp, cmd, arg);
    1333          61 :         ext4_fc_stop_update(file_inode(filp));
    1334             : 
    1335          61 :         return ret;
    1336             : }
    1337             : 
    1338             : #ifdef CONFIG_COMPAT
    1339           0 : long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    1340             : {
    1341             :         /* These are just misnamed, they actually get/put from/to user an int */
    1342           0 :         switch (cmd) {
    1343           0 :         case FS_IOC32_GETFLAGS:
    1344           0 :                 cmd = FS_IOC_GETFLAGS;
    1345           0 :                 break;
    1346           0 :         case FS_IOC32_SETFLAGS:
    1347           0 :                 cmd = FS_IOC_SETFLAGS;
    1348           0 :                 break;
    1349           0 :         case EXT4_IOC32_GETVERSION:
    1350           0 :                 cmd = EXT4_IOC_GETVERSION;
    1351           0 :                 break;
    1352           0 :         case EXT4_IOC32_SETVERSION:
    1353           0 :                 cmd = EXT4_IOC_SETVERSION;
    1354           0 :                 break;
    1355           0 :         case EXT4_IOC32_GROUP_EXTEND:
    1356           0 :                 cmd = EXT4_IOC_GROUP_EXTEND;
    1357           0 :                 break;
    1358           0 :         case EXT4_IOC32_GETVERSION_OLD:
    1359           0 :                 cmd = EXT4_IOC_GETVERSION_OLD;
    1360           0 :                 break;
    1361           0 :         case EXT4_IOC32_SETVERSION_OLD:
    1362           0 :                 cmd = EXT4_IOC_SETVERSION_OLD;
    1363           0 :                 break;
    1364           0 :         case EXT4_IOC32_GETRSVSZ:
    1365           0 :                 cmd = EXT4_IOC_GETRSVSZ;
    1366           0 :                 break;
    1367           0 :         case EXT4_IOC32_SETRSVSZ:
    1368           0 :                 cmd = EXT4_IOC_SETRSVSZ;
    1369           0 :                 break;
    1370           0 :         case EXT4_IOC32_GROUP_ADD: {
    1371           0 :                 struct compat_ext4_new_group_input __user *uinput;
    1372           0 :                 struct ext4_new_group_data input;
    1373           0 :                 int err;
    1374             : 
    1375           0 :                 uinput = compat_ptr(arg);
    1376           0 :                 err = get_user(input.group, &uinput->group);
    1377           0 :                 err |= get_user(input.block_bitmap, &uinput->block_bitmap);
    1378           0 :                 err |= get_user(input.inode_bitmap, &uinput->inode_bitmap);
    1379           0 :                 err |= get_user(input.inode_table, &uinput->inode_table);
    1380           0 :                 err |= get_user(input.blocks_count, &uinput->blocks_count);
    1381           0 :                 err |= get_user(input.reserved_blocks,
    1382             :                                 &uinput->reserved_blocks);
    1383           0 :                 if (err)
    1384             :                         return -EFAULT;
    1385           0 :                 return ext4_ioctl_group_add(file, &input);
    1386             :         }
    1387             :         case EXT4_IOC_MOVE_EXT:
    1388             :         case EXT4_IOC_RESIZE_FS:
    1389             :         case FITRIM:
    1390             :         case EXT4_IOC_PRECACHE_EXTENTS:
    1391             :         case FS_IOC_SET_ENCRYPTION_POLICY:
    1392             :         case FS_IOC_GET_ENCRYPTION_PWSALT:
    1393             :         case FS_IOC_GET_ENCRYPTION_POLICY:
    1394             :         case FS_IOC_GET_ENCRYPTION_POLICY_EX:
    1395             :         case FS_IOC_ADD_ENCRYPTION_KEY:
    1396             :         case FS_IOC_REMOVE_ENCRYPTION_KEY:
    1397             :         case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS:
    1398             :         case FS_IOC_GET_ENCRYPTION_KEY_STATUS:
    1399             :         case FS_IOC_GET_ENCRYPTION_NONCE:
    1400             :         case EXT4_IOC_SHUTDOWN:
    1401             :         case FS_IOC_GETFSMAP:
    1402             :         case FS_IOC_ENABLE_VERITY:
    1403             :         case FS_IOC_MEASURE_VERITY:
    1404             :         case FS_IOC_READ_VERITY_METADATA:
    1405             :         case EXT4_IOC_CLEAR_ES_CACHE:
    1406             :         case EXT4_IOC_GETSTATE:
    1407             :         case EXT4_IOC_GET_ES_CACHE:
    1408             :         case FS_IOC_FSGETXATTR:
    1409             :         case FS_IOC_FSSETXATTR:
    1410             :                 break;
    1411             :         default:
    1412             :                 return -ENOIOCTLCMD;
    1413             :         }
    1414           0 :         return ext4_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
    1415             : }
    1416             : #endif

Generated by: LCOV version 1.14