linux/fs/ext4/ioctl.c
<<
>>
Prefs
   1/*
   2 * linux/fs/ext4/ioctl.c
   3 *
   4 * Copyright (C) 1993, 1994, 1995
   5 * Remy Card (card@masi.ibp.fr)
   6 * Laboratoire MASI - Institut Blaise Pascal
   7 * Universite Pierre et Marie Curie (Paris VI)
   8 */
   9
  10#include <linux/fs.h>
  11#include <linux/capability.h>
  12#include <linux/time.h>
  13#include <linux/compat.h>
  14#include <linux/mount.h>
  15#include <linux/file.h>
  16#include <linux/random.h>
  17#include <linux/quotaops.h>
  18#include <asm/uaccess.h>
  19#include "ext4_jbd2.h"
  20#include "ext4.h"
  21
  22#define MAX_32_NUM ((((unsigned long long) 1) << 32) - 1)
  23
  24/**
  25 * Swap memory between @a and @b for @len bytes.
  26 *
  27 * @a:          pointer to first memory area
  28 * @b:          pointer to second memory area
  29 * @len:        number of bytes to swap
  30 *
  31 */
  32static void memswap(void *a, void *b, size_t len)
  33{
  34        unsigned char *ap, *bp;
  35
  36        ap = (unsigned char *)a;
  37        bp = (unsigned char *)b;
  38        while (len-- > 0) {
  39                swap(*ap, *bp);
  40                ap++;
  41                bp++;
  42        }
  43}
  44
  45/**
  46 * Swap i_data and associated attributes between @inode1 and @inode2.
  47 * This function is used for the primary swap between inode1 and inode2
  48 * and also to revert this primary swap in case of errors.
  49 *
  50 * Therefore you have to make sure, that calling this method twice
  51 * will revert all changes.
  52 *
  53 * @inode1:     pointer to first inode
  54 * @inode2:     pointer to second inode
  55 */
  56static void swap_inode_data(struct inode *inode1, struct inode *inode2)
  57{
  58        loff_t isize;
  59        struct ext4_inode_info *ei1;
  60        struct ext4_inode_info *ei2;
  61
  62        ei1 = EXT4_I(inode1);
  63        ei2 = EXT4_I(inode2);
  64
  65        memswap(&inode1->i_flags, &inode2->i_flags, sizeof(inode1->i_flags));
  66        memswap(&inode1->i_version, &inode2->i_version,
  67                  sizeof(inode1->i_version));
  68        memswap(&inode1->i_blocks, &inode2->i_blocks,
  69                  sizeof(inode1->i_blocks));
  70        memswap(&inode1->i_bytes, &inode2->i_bytes, sizeof(inode1->i_bytes));
  71        memswap(&inode1->i_atime, &inode2->i_atime, sizeof(inode1->i_atime));
  72        memswap(&inode1->i_mtime, &inode2->i_mtime, sizeof(inode1->i_mtime));
  73
  74        memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
  75        memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags));
  76        memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize));
  77        ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS);
  78        ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS);
  79
  80        isize = i_size_read(inode1);
  81        i_size_write(inode1, i_size_read(inode2));
  82        i_size_write(inode2, isize);
  83}
  84
  85/**
  86 * Swap the information from the given @inode and the inode
  87 * EXT4_BOOT_LOADER_INO. It will basically swap i_data and all other
  88 * important fields of the inodes.
  89 *
  90 * @sb:         the super block of the filesystem
  91 * @inode:      the inode to swap with EXT4_BOOT_LOADER_INO
  92 *
  93 */
  94static long swap_inode_boot_loader(struct super_block *sb,
  95                                struct inode *inode)
  96{
  97        handle_t *handle;
  98        int err;
  99        struct inode *inode_bl;
 100        struct ext4_inode_info *ei_bl;
 101        struct ext4_sb_info *sbi = EXT4_SB(sb);
 102
 103        if (inode->i_nlink != 1 || !S_ISREG(inode->i_mode))
 104                return -EINVAL;
 105
 106        if (!inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
 107                return -EPERM;
 108
 109        inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO);
 110        if (IS_ERR(inode_bl))
 111                return PTR_ERR(inode_bl);
 112        ei_bl = EXT4_I(inode_bl);
 113
 114        filemap_flush(inode->i_mapping);
 115        filemap_flush(inode_bl->i_mapping);
 116
 117        /* Protect orig inodes against a truncate and make sure,
 118         * that only 1 swap_inode_boot_loader is running. */
 119        lock_two_nondirectories(inode, inode_bl);
 120
 121        truncate_inode_pages(&inode->i_data, 0);
 122        truncate_inode_pages(&inode_bl->i_data, 0);
 123
 124        /* Wait for all existing dio workers */
 125        ext4_inode_block_unlocked_dio(inode);
 126        ext4_inode_block_unlocked_dio(inode_bl);
 127        inode_dio_wait(inode);
 128        inode_dio_wait(inode_bl);
 129
 130        handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
 131        if (IS_ERR(handle)) {
 132                err = -EINVAL;
 133                goto journal_err_out;
 134        }
 135
 136        /* Protect extent tree against block allocations via delalloc */
 137        ext4_double_down_write_data_sem(inode, inode_bl);
 138
 139        if (inode_bl->i_nlink == 0) {
 140                /* this inode has never been used as a BOOT_LOADER */
 141                set_nlink(inode_bl, 1);
 142                i_uid_write(inode_bl, 0);
 143                i_gid_write(inode_bl, 0);
 144                inode_bl->i_flags = 0;
 145                ei_bl->i_flags = 0;
 146                inode_bl->i_version = 1;
 147                i_size_write(inode_bl, 0);
 148                inode_bl->i_mode = S_IFREG;
 149                if (ext4_has_feature_extents(sb)) {
 150                        ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS);
 151                        ext4_ext_tree_init(handle, inode_bl);
 152                } else
 153                        memset(ei_bl->i_data, 0, sizeof(ei_bl->i_data));
 154        }
 155
 156        swap_inode_data(inode, inode_bl);
 157
 158        inode->i_ctime = inode_bl->i_ctime = ext4_current_time(inode);
 159
 160        spin_lock(&sbi->s_next_gen_lock);
 161        inode->i_generation = sbi->s_next_generation++;
 162        inode_bl->i_generation = sbi->s_next_generation++;
 163        spin_unlock(&sbi->s_next_gen_lock);
 164
 165        ext4_discard_preallocations(inode);
 166
 167        err = ext4_mark_inode_dirty(handle, inode);
 168        if (err < 0) {
 169                ext4_warning(inode->i_sb,
 170                        "couldn't mark inode #%lu dirty (err %d)",
 171                        inode->i_ino, err);
 172                /* Revert all changes: */
 173                swap_inode_data(inode, inode_bl);
 174        } else {
 175                err = ext4_mark_inode_dirty(handle, inode_bl);
 176                if (err < 0) {
 177                        ext4_warning(inode_bl->i_sb,
 178                                "couldn't mark inode #%lu dirty (err %d)",
 179                                inode_bl->i_ino, err);
 180                        /* Revert all changes: */
 181                        swap_inode_data(inode, inode_bl);
 182                        ext4_mark_inode_dirty(handle, inode);
 183                }
 184        }
 185        ext4_journal_stop(handle);
 186        ext4_double_up_write_data_sem(inode, inode_bl);
 187
 188journal_err_out:
 189        ext4_inode_resume_unlocked_dio(inode);
 190        ext4_inode_resume_unlocked_dio(inode_bl);
 191        unlock_two_nondirectories(inode, inode_bl);
 192        iput(inode_bl);
 193        return err;
 194}
 195
 196static int uuid_is_zero(__u8 u[16])
 197{
 198        int     i;
 199
 200        for (i = 0; i < 16; i++)
 201                if (u[i])
 202                        return 0;
 203        return 1;
 204}
 205
 206static int ext4_ioctl_setflags(struct inode *inode,
 207                               unsigned int flags)
 208{
 209        struct ext4_inode_info *ei = EXT4_I(inode);
 210        handle_t *handle = NULL;
 211        int err = -EPERM, migrate = 0;
 212        struct ext4_iloc iloc;
 213        unsigned int oldflags, mask, i;
 214        unsigned int jflag;
 215
 216        /* Is it quota file? Do not allow user to mess with it */
 217        if (IS_NOQUOTA(inode))
 218                goto flags_out;
 219
 220        oldflags = ei->i_flags;
 221
 222        /* The JOURNAL_DATA flag is modifiable only by root */
 223        jflag = flags & EXT4_JOURNAL_DATA_FL;
 224
 225        /*
 226         * The IMMUTABLE and APPEND_ONLY flags can only be changed by
 227         * the relevant capability.
 228         *
 229         * This test looks nicer. Thanks to Pauline Middelink
 230         */
 231        if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
 232                if (!capable(CAP_LINUX_IMMUTABLE))
 233                        goto flags_out;
 234        }
 235
 236        /*
 237         * The JOURNAL_DATA flag can only be changed by
 238         * the relevant capability.
 239         */
 240        if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
 241                if (!capable(CAP_SYS_RESOURCE))
 242                        goto flags_out;
 243        }
 244        if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
 245                migrate = 1;
 246
 247        if (flags & EXT4_EOFBLOCKS_FL) {
 248                /* we don't support adding EOFBLOCKS flag */
 249                if (!(oldflags & EXT4_EOFBLOCKS_FL)) {
 250                        err = -EOPNOTSUPP;
 251                        goto flags_out;
 252                }
 253        } else if (oldflags & EXT4_EOFBLOCKS_FL)
 254                ext4_truncate(inode);
 255
 256        handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
 257        if (IS_ERR(handle)) {
 258                err = PTR_ERR(handle);
 259                goto flags_out;
 260        }
 261        if (IS_SYNC(inode))
 262                ext4_handle_sync(handle);
 263        err = ext4_reserve_inode_write(handle, inode, &iloc);
 264        if (err)
 265                goto flags_err;
 266
 267        for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
 268                if (!(mask & EXT4_FL_USER_MODIFIABLE))
 269                        continue;
 270                if (mask & flags)
 271                        ext4_set_inode_flag(inode, i);
 272                else
 273                        ext4_clear_inode_flag(inode, i);
 274        }
 275
 276        ext4_set_inode_flags(inode);
 277        inode->i_ctime = ext4_current_time(inode);
 278
 279        err = ext4_mark_iloc_dirty(handle, inode, &iloc);
 280flags_err:
 281        ext4_journal_stop(handle);
 282        if (err)
 283                goto flags_out;
 284
 285        if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
 286                err = ext4_change_inode_journal_flag(inode, jflag);
 287        if (err)
 288                goto flags_out;
 289        if (migrate) {
 290                if (flags & EXT4_EXTENTS_FL)
 291                        err = ext4_ext_migrate(inode);
 292                else
 293                        err = ext4_ind_migrate(inode);
 294        }
 295
 296flags_out:
 297        return err;
 298}
 299
 300#ifdef CONFIG_QUOTA
 301static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
 302{
 303        struct inode *inode = file_inode(filp);
 304        struct super_block *sb = inode->i_sb;
 305        struct ext4_inode_info *ei = EXT4_I(inode);
 306        int err, rc;
 307        handle_t *handle;
 308        kprojid_t kprojid;
 309        struct ext4_iloc iloc;
 310        struct ext4_inode *raw_inode;
 311
 312        if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
 313                        EXT4_FEATURE_RO_COMPAT_PROJECT)) {
 314                if (projid != EXT4_DEF_PROJID)
 315                        return -EOPNOTSUPP;
 316                else
 317                        return 0;
 318        }
 319
 320        if (EXT4_INODE_SIZE(sb) <= EXT4_GOOD_OLD_INODE_SIZE)
 321                return -EOPNOTSUPP;
 322
 323        kprojid = make_kprojid(&init_user_ns, (projid_t)projid);
 324
 325        if (projid_eq(kprojid, EXT4_I(inode)->i_projid))
 326                return 0;
 327
 328        err = mnt_want_write_file(filp);
 329        if (err)
 330                return err;
 331
 332        err = -EPERM;
 333        inode_lock(inode);
 334        /* Is it quota file? Do not allow user to mess with it */
 335        if (IS_NOQUOTA(inode))
 336                goto out_unlock;
 337
 338        err = ext4_get_inode_loc(inode, &iloc);
 339        if (err)
 340                goto out_unlock;
 341
 342        raw_inode = ext4_raw_inode(&iloc);
 343        if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
 344                err = -EOVERFLOW;
 345                brelse(iloc.bh);
 346                goto out_unlock;
 347        }
 348        brelse(iloc.bh);
 349
 350        dquot_initialize(inode);
 351
 352        handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
 353                EXT4_QUOTA_INIT_BLOCKS(sb) +
 354                EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
 355        if (IS_ERR(handle)) {
 356                err = PTR_ERR(handle);
 357                goto out_unlock;
 358        }
 359
 360        err = ext4_reserve_inode_write(handle, inode, &iloc);
 361        if (err)
 362                goto out_stop;
 363
 364        if (sb_has_quota_limits_enabled(sb, PRJQUOTA)) {
 365                struct dquot *transfer_to[MAXQUOTAS] = { };
 366
 367                transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
 368                if (transfer_to[PRJQUOTA]) {
 369                        err = __dquot_transfer(inode, transfer_to);
 370                        dqput(transfer_to[PRJQUOTA]);
 371                        if (err)
 372                                goto out_dirty;
 373                }
 374        }
 375        EXT4_I(inode)->i_projid = kprojid;
 376        inode->i_ctime = ext4_current_time(inode);
 377out_dirty:
 378        rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
 379        if (!err)
 380                err = rc;
 381out_stop:
 382        ext4_journal_stop(handle);
 383out_unlock:
 384        inode_unlock(inode);
 385        mnt_drop_write_file(filp);
 386        return err;
 387}
 388#else
 389static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
 390{
 391        if (projid != EXT4_DEF_PROJID)
 392                return -EOPNOTSUPP;
 393        return 0;
 394}
 395#endif
 396
 397/* Transfer internal flags to xflags */
 398static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
 399{
 400        __u32 xflags = 0;
 401
 402        if (iflags & EXT4_SYNC_FL)
 403                xflags |= FS_XFLAG_SYNC;
 404        if (iflags & EXT4_IMMUTABLE_FL)
 405                xflags |= FS_XFLAG_IMMUTABLE;
 406        if (iflags & EXT4_APPEND_FL)
 407                xflags |= FS_XFLAG_APPEND;
 408        if (iflags & EXT4_NODUMP_FL)
 409                xflags |= FS_XFLAG_NODUMP;
 410        if (iflags & EXT4_NOATIME_FL)
 411                xflags |= FS_XFLAG_NOATIME;
 412        if (iflags & EXT4_PROJINHERIT_FL)
 413                xflags |= FS_XFLAG_PROJINHERIT;
 414        return xflags;
 415}
 416
 417/* Transfer xflags flags to internal */
 418static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
 419{
 420        unsigned long iflags = 0;
 421
 422        if (xflags & FS_XFLAG_SYNC)
 423                iflags |= EXT4_SYNC_FL;
 424        if (xflags & FS_XFLAG_IMMUTABLE)
 425                iflags |= EXT4_IMMUTABLE_FL;
 426        if (xflags & FS_XFLAG_APPEND)
 427                iflags |= EXT4_APPEND_FL;
 428        if (xflags & FS_XFLAG_NODUMP)
 429                iflags |= EXT4_NODUMP_FL;
 430        if (xflags & FS_XFLAG_NOATIME)
 431                iflags |= EXT4_NOATIME_FL;
 432        if (xflags & FS_XFLAG_PROJINHERIT)
 433                iflags |= EXT4_PROJINHERIT_FL;
 434
 435        return iflags;
 436}
 437
 438long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 439{
 440        struct inode *inode = file_inode(filp);
 441        struct super_block *sb = inode->i_sb;
 442        struct ext4_inode_info *ei = EXT4_I(inode);
 443        unsigned int flags;
 444
 445        ext4_debug("cmd = %u, arg = %lu\n", cmd, arg);
 446
 447        switch (cmd) {
 448        case EXT4_IOC_GETFLAGS:
 449                ext4_get_inode_flags(ei);
 450                flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
 451                return put_user(flags, (int __user *) arg);
 452        case EXT4_IOC_SETFLAGS: {
 453                int err;
 454
 455                if (!inode_owner_or_capable(inode))
 456                        return -EACCES;
 457
 458                if (get_user(flags, (int __user *) arg))
 459                        return -EFAULT;
 460
 461                err = mnt_want_write_file(filp);
 462                if (err)
 463                        return err;
 464
 465                flags = ext4_mask_flags(inode->i_mode, flags);
 466
 467                inode_lock(inode);
 468                err = ext4_ioctl_setflags(inode, flags);
 469                inode_unlock(inode);
 470                mnt_drop_write_file(filp);
 471                return err;
 472        }
 473        case EXT4_IOC_GETVERSION:
 474        case EXT4_IOC_GETVERSION_OLD:
 475                return put_user(inode->i_generation, (int __user *) arg);
 476        case EXT4_IOC_SETVERSION:
 477        case EXT4_IOC_SETVERSION_OLD: {
 478                handle_t *handle;
 479                struct ext4_iloc iloc;
 480                __u32 generation;
 481                int err;
 482
 483                if (!inode_owner_or_capable(inode))
 484                        return -EPERM;
 485
 486                if (ext4_has_metadata_csum(inode->i_sb)) {
 487                        ext4_warning(sb, "Setting inode version is not "
 488                                     "supported with metadata_csum enabled.");
 489                        return -ENOTTY;
 490                }
 491
 492                err = mnt_want_write_file(filp);
 493                if (err)
 494                        return err;
 495                if (get_user(generation, (int __user *) arg)) {
 496                        err = -EFAULT;
 497                        goto setversion_out;
 498                }
 499
 500                inode_lock(inode);
 501                handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
 502                if (IS_ERR(handle)) {
 503                        err = PTR_ERR(handle);
 504                        goto unlock_out;
 505                }
 506                err = ext4_reserve_inode_write(handle, inode, &iloc);
 507                if (err == 0) {
 508                        inode->i_ctime = ext4_current_time(inode);
 509                        inode->i_generation = generation;
 510                        err = ext4_mark_iloc_dirty(handle, inode, &iloc);
 511                }
 512                ext4_journal_stop(handle);
 513
 514unlock_out:
 515                inode_unlock(inode);
 516setversion_out:
 517                mnt_drop_write_file(filp);
 518                return err;
 519        }
 520        case EXT4_IOC_GROUP_EXTEND: {
 521                ext4_fsblk_t n_blocks_count;
 522                int err, err2=0;
 523
 524                err = ext4_resize_begin(sb);
 525                if (err)
 526                        return err;
 527
 528                if (get_user(n_blocks_count, (__u32 __user *)arg)) {
 529                        err = -EFAULT;
 530                        goto group_extend_out;
 531                }
 532
 533                if (ext4_has_feature_bigalloc(sb)) {
 534                        ext4_msg(sb, KERN_ERR,
 535                                 "Online resizing not supported with bigalloc");
 536                        err = -EOPNOTSUPP;
 537                        goto group_extend_out;
 538                }
 539
 540                err = mnt_want_write_file(filp);
 541                if (err)
 542                        goto group_extend_out;
 543
 544                err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
 545                if (EXT4_SB(sb)->s_journal) {
 546                        jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
 547                        err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
 548                        jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
 549                }
 550                if (err == 0)
 551                        err = err2;
 552                mnt_drop_write_file(filp);
 553group_extend_out:
 554                ext4_resize_end(sb);
 555                return err;
 556        }
 557
 558        case EXT4_IOC_MOVE_EXT: {
 559                struct move_extent me;
 560                struct fd donor;
 561                int err;
 562
 563                if (!(filp->f_mode & FMODE_READ) ||
 564                    !(filp->f_mode & FMODE_WRITE))
 565                        return -EBADF;
 566
 567                if (copy_from_user(&me,
 568                        (struct move_extent __user *)arg, sizeof(me)))
 569                        return -EFAULT;
 570                me.moved_len = 0;
 571
 572                donor = fdget(me.donor_fd);
 573                if (!donor.file)
 574                        return -EBADF;
 575
 576                if (!(donor.file->f_mode & FMODE_WRITE)) {
 577                        err = -EBADF;
 578                        goto mext_out;
 579                }
 580
 581                if (ext4_has_feature_bigalloc(sb)) {
 582                        ext4_msg(sb, KERN_ERR,
 583                                 "Online defrag not supported with bigalloc");
 584                        err = -EOPNOTSUPP;
 585                        goto mext_out;
 586                } else if (IS_DAX(inode)) {
 587                        ext4_msg(sb, KERN_ERR,
 588                                 "Online defrag not supported with DAX");
 589                        err = -EOPNOTSUPP;
 590                        goto mext_out;
 591                }
 592
 593                err = mnt_want_write_file(filp);
 594                if (err)
 595                        goto mext_out;
 596
 597                err = ext4_move_extents(filp, donor.file, me.orig_start,
 598                                        me.donor_start, me.len, &me.moved_len);
 599                mnt_drop_write_file(filp);
 600
 601                if (copy_to_user((struct move_extent __user *)arg,
 602                                 &me, sizeof(me)))
 603                        err = -EFAULT;
 604mext_out:
 605                fdput(donor);
 606                return err;
 607        }
 608
 609        case EXT4_IOC_GROUP_ADD: {
 610                struct ext4_new_group_data input;
 611                int err, err2=0;
 612
 613                err = ext4_resize_begin(sb);
 614                if (err)
 615                        return err;
 616
 617                if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
 618                                sizeof(input))) {
 619                        err = -EFAULT;
 620                        goto group_add_out;
 621                }
 622
 623                if (ext4_has_feature_bigalloc(sb)) {
 624                        ext4_msg(sb, KERN_ERR,
 625                                 "Online resizing not supported with bigalloc");
 626                        err = -EOPNOTSUPP;
 627                        goto group_add_out;
 628                }
 629
 630                err = mnt_want_write_file(filp);
 631                if (err)
 632                        goto group_add_out;
 633
 634                err = ext4_group_add(sb, &input);
 635                if (EXT4_SB(sb)->s_journal) {
 636                        jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
 637                        err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
 638                        jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
 639                }
 640                if (err == 0)
 641                        err = err2;
 642                mnt_drop_write_file(filp);
 643                if (!err && ext4_has_group_desc_csum(sb) &&
 644                    test_opt(sb, INIT_INODE_TABLE))
 645                        err = ext4_register_li_request(sb, input.group);
 646group_add_out:
 647                ext4_resize_end(sb);
 648                return err;
 649        }
 650
 651        case EXT4_IOC_MIGRATE:
 652        {
 653                int err;
 654                if (!inode_owner_or_capable(inode))
 655                        return -EACCES;
 656
 657                err = mnt_want_write_file(filp);
 658                if (err)
 659                        return err;
 660                /*
 661                 * inode_mutex prevent write and truncate on the file.
 662                 * Read still goes through. We take i_data_sem in
 663                 * ext4_ext_swap_inode_data before we switch the
 664                 * inode format to prevent read.
 665                 */
 666                inode_lock((inode));
 667                err = ext4_ext_migrate(inode);
 668                inode_unlock((inode));
 669                mnt_drop_write_file(filp);
 670                return err;
 671        }
 672
 673        case EXT4_IOC_ALLOC_DA_BLKS:
 674        {
 675                int err;
 676                if (!inode_owner_or_capable(inode))
 677                        return -EACCES;
 678
 679                err = mnt_want_write_file(filp);
 680                if (err)
 681                        return err;
 682                err = ext4_alloc_da_blocks(inode);
 683                mnt_drop_write_file(filp);
 684                return err;
 685        }
 686
 687        case EXT4_IOC_SWAP_BOOT:
 688        {
 689                int err;
 690                if (!(filp->f_mode & FMODE_WRITE))
 691                        return -EBADF;
 692                err = mnt_want_write_file(filp);
 693                if (err)
 694                        return err;
 695                err = swap_inode_boot_loader(sb, inode);
 696                mnt_drop_write_file(filp);
 697                return err;
 698        }
 699
 700        case EXT4_IOC_RESIZE_FS: {
 701                ext4_fsblk_t n_blocks_count;
 702                int err = 0, err2 = 0;
 703                ext4_group_t o_group = EXT4_SB(sb)->s_groups_count;
 704
 705                if (ext4_has_feature_bigalloc(sb)) {
 706                        ext4_msg(sb, KERN_ERR,
 707                                 "Online resizing not (yet) supported with bigalloc");
 708                        return -EOPNOTSUPP;
 709                }
 710
 711                if (copy_from_user(&n_blocks_count, (__u64 __user *)arg,
 712                                   sizeof(__u64))) {
 713                        return -EFAULT;
 714                }
 715
 716                err = ext4_resize_begin(sb);
 717                if (err)
 718                        return err;
 719
 720                err = mnt_want_write_file(filp);
 721                if (err)
 722                        goto resizefs_out;
 723
 724                err = ext4_resize_fs(sb, n_blocks_count);
 725                if (EXT4_SB(sb)->s_journal) {
 726                        jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
 727                        err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
 728                        jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
 729                }
 730                if (err == 0)
 731                        err = err2;
 732                mnt_drop_write_file(filp);
 733                if (!err && (o_group > EXT4_SB(sb)->s_groups_count) &&
 734                    ext4_has_group_desc_csum(sb) &&
 735                    test_opt(sb, INIT_INODE_TABLE))
 736                        err = ext4_register_li_request(sb, o_group);
 737
 738resizefs_out:
 739                ext4_resize_end(sb);
 740                return err;
 741        }
 742
 743        case FITRIM:
 744        {
 745                struct request_queue *q = bdev_get_queue(sb->s_bdev);
 746                struct fstrim_range range;
 747                int ret = 0;
 748
 749                if (!capable(CAP_SYS_ADMIN))
 750                        return -EPERM;
 751
 752                if (!blk_queue_discard(q))
 753                        return -EOPNOTSUPP;
 754
 755                if (copy_from_user(&range, (struct fstrim_range __user *)arg,
 756                    sizeof(range)))
 757                        return -EFAULT;
 758
 759                range.minlen = max((unsigned int)range.minlen,
 760                                   q->limits.discard_granularity);
 761                ret = ext4_trim_fs(sb, &range);
 762                if (ret < 0)
 763                        return ret;
 764
 765                if (copy_to_user((struct fstrim_range __user *)arg, &range,
 766                    sizeof(range)))
 767                        return -EFAULT;
 768
 769                return 0;
 770        }
 771        case EXT4_IOC_PRECACHE_EXTENTS:
 772                return ext4_ext_precache(inode);
 773        case EXT4_IOC_SET_ENCRYPTION_POLICY: {
 774#ifdef CONFIG_EXT4_FS_ENCRYPTION
 775                struct ext4_encryption_policy policy;
 776                int err = 0;
 777
 778                if (copy_from_user(&policy,
 779                                   (struct ext4_encryption_policy __user *)arg,
 780                                   sizeof(policy))) {
 781                        err = -EFAULT;
 782                        goto encryption_policy_out;
 783                }
 784
 785                err = ext4_process_policy(&policy, inode);
 786encryption_policy_out:
 787                return err;
 788#else
 789                return -EOPNOTSUPP;
 790#endif
 791        }
 792        case EXT4_IOC_GET_ENCRYPTION_PWSALT: {
 793                int err, err2;
 794                struct ext4_sb_info *sbi = EXT4_SB(sb);
 795                handle_t *handle;
 796
 797                if (!ext4_sb_has_crypto(sb))
 798                        return -EOPNOTSUPP;
 799                if (uuid_is_zero(sbi->s_es->s_encrypt_pw_salt)) {
 800                        err = mnt_want_write_file(filp);
 801                        if (err)
 802                                return err;
 803                        handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1);
 804                        if (IS_ERR(handle)) {
 805                                err = PTR_ERR(handle);
 806                                goto pwsalt_err_exit;
 807                        }
 808                        err = ext4_journal_get_write_access(handle, sbi->s_sbh);
 809                        if (err)
 810                                goto pwsalt_err_journal;
 811                        generate_random_uuid(sbi->s_es->s_encrypt_pw_salt);
 812                        err = ext4_handle_dirty_metadata(handle, NULL,
 813                                                         sbi->s_sbh);
 814                pwsalt_err_journal:
 815                        err2 = ext4_journal_stop(handle);
 816                        if (err2 && !err)
 817                                err = err2;
 818                pwsalt_err_exit:
 819                        mnt_drop_write_file(filp);
 820                        if (err)
 821                                return err;
 822                }
 823                if (copy_to_user((void __user *) arg,
 824                                 sbi->s_es->s_encrypt_pw_salt, 16))
 825                        return -EFAULT;
 826                return 0;
 827        }
 828        case EXT4_IOC_GET_ENCRYPTION_POLICY: {
 829#ifdef CONFIG_EXT4_FS_ENCRYPTION
 830                struct ext4_encryption_policy policy;
 831                int err = 0;
 832
 833                if (!ext4_encrypted_inode(inode))
 834                        return -ENOENT;
 835                err = ext4_get_policy(inode, &policy);
 836                if (err)
 837                        return err;
 838                if (copy_to_user((void __user *)arg, &policy, sizeof(policy)))
 839                        return -EFAULT;
 840                return 0;
 841#else
 842                return -EOPNOTSUPP;
 843#endif
 844        }
 845        case EXT4_IOC_FSGETXATTR:
 846        {
 847                struct fsxattr fa;
 848
 849                memset(&fa, 0, sizeof(struct fsxattr));
 850                ext4_get_inode_flags(ei);
 851                fa.fsx_xflags = ext4_iflags_to_xflags(ei->i_flags & EXT4_FL_USER_VISIBLE);
 852
 853                if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
 854                                EXT4_FEATURE_RO_COMPAT_PROJECT)) {
 855                        fa.fsx_projid = (__u32)from_kprojid(&init_user_ns,
 856                                EXT4_I(inode)->i_projid);
 857                }
 858
 859                if (copy_to_user((struct fsxattr __user *)arg,
 860                                 &fa, sizeof(fa)))
 861                        return -EFAULT;
 862                return 0;
 863        }
 864        case EXT4_IOC_FSSETXATTR:
 865        {
 866                struct fsxattr fa;
 867                int err;
 868
 869                if (copy_from_user(&fa, (struct fsxattr __user *)arg,
 870                                   sizeof(fa)))
 871                        return -EFAULT;
 872
 873                /* Make sure caller has proper permission */
 874                if (!inode_owner_or_capable(inode))
 875                        return -EACCES;
 876
 877                err = mnt_want_write_file(filp);
 878                if (err)
 879                        return err;
 880
 881                flags = ext4_xflags_to_iflags(fa.fsx_xflags);
 882                flags = ext4_mask_flags(inode->i_mode, flags);
 883
 884                inode_lock(inode);
 885                flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
 886                         (flags & EXT4_FL_XFLAG_VISIBLE);
 887                err = ext4_ioctl_setflags(inode, flags);
 888                inode_unlock(inode);
 889                mnt_drop_write_file(filp);
 890                if (err)
 891                        return err;
 892
 893                err = ext4_ioctl_setproject(filp, fa.fsx_projid);
 894                if (err)
 895                        return err;
 896
 897                return 0;
 898        }
 899        default:
 900                return -ENOTTY;
 901        }
 902}
 903
 904#ifdef CONFIG_COMPAT
 905long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 906{
 907        /* These are just misnamed, they actually get/put from/to user an int */
 908        switch (cmd) {
 909        case EXT4_IOC32_GETFLAGS:
 910                cmd = EXT4_IOC_GETFLAGS;
 911                break;
 912        case EXT4_IOC32_SETFLAGS:
 913                cmd = EXT4_IOC_SETFLAGS;
 914                break;
 915        case EXT4_IOC32_GETVERSION:
 916                cmd = EXT4_IOC_GETVERSION;
 917                break;
 918        case EXT4_IOC32_SETVERSION:
 919                cmd = EXT4_IOC_SETVERSION;
 920                break;
 921        case EXT4_IOC32_GROUP_EXTEND:
 922                cmd = EXT4_IOC_GROUP_EXTEND;
 923                break;
 924        case EXT4_IOC32_GETVERSION_OLD:
 925                cmd = EXT4_IOC_GETVERSION_OLD;
 926                break;
 927        case EXT4_IOC32_SETVERSION_OLD:
 928                cmd = EXT4_IOC_SETVERSION_OLD;
 929                break;
 930        case EXT4_IOC32_GETRSVSZ:
 931                cmd = EXT4_IOC_GETRSVSZ;
 932                break;
 933        case EXT4_IOC32_SETRSVSZ:
 934                cmd = EXT4_IOC_SETRSVSZ;
 935                break;
 936        case EXT4_IOC32_GROUP_ADD: {
 937                struct compat_ext4_new_group_input __user *uinput;
 938                struct ext4_new_group_input input;
 939                mm_segment_t old_fs;
 940                int err;
 941
 942                uinput = compat_ptr(arg);
 943                err = get_user(input.group, &uinput->group);
 944                err |= get_user(input.block_bitmap, &uinput->block_bitmap);
 945                err |= get_user(input.inode_bitmap, &uinput->inode_bitmap);
 946                err |= get_user(input.inode_table, &uinput->inode_table);
 947                err |= get_user(input.blocks_count, &uinput->blocks_count);
 948                err |= get_user(input.reserved_blocks,
 949                                &uinput->reserved_blocks);
 950                if (err)
 951                        return -EFAULT;
 952                old_fs = get_fs();
 953                set_fs(KERNEL_DS);
 954                err = ext4_ioctl(file, EXT4_IOC_GROUP_ADD,
 955                                 (unsigned long) &input);
 956                set_fs(old_fs);
 957                return err;
 958        }
 959        case EXT4_IOC_MOVE_EXT:
 960        case EXT4_IOC_RESIZE_FS:
 961        case EXT4_IOC_PRECACHE_EXTENTS:
 962        case EXT4_IOC_SET_ENCRYPTION_POLICY:
 963        case EXT4_IOC_GET_ENCRYPTION_PWSALT:
 964        case EXT4_IOC_GET_ENCRYPTION_POLICY:
 965                break;
 966        default:
 967                return -ENOIOCTLCMD;
 968        }
 969        return ext4_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
 970}
 971#endif
 972