linux/fs/nilfs2/ioctl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * ioctl.c - NILFS ioctl operations.
   4 *
   5 * Copyright (C) 2007, 2008 Nippon Telegraph and Telephone Corporation.
   6 *
   7 * Written by Koji Sato.
   8 */
   9
  10#include <linux/fs.h>
  11#include <linux/wait.h>
  12#include <linux/slab.h>
  13#include <linux/capability.h>   /* capable() */
  14#include <linux/uaccess.h>      /* copy_from_user(), copy_to_user() */
  15#include <linux/vmalloc.h>
  16#include <linux/compat.h>       /* compat_ptr() */
  17#include <linux/mount.h>        /* mnt_want_write_file(), mnt_drop_write_file() */
  18#include <linux/buffer_head.h>
  19#include "nilfs.h"
  20#include "segment.h"
  21#include "bmap.h"
  22#include "cpfile.h"
  23#include "sufile.h"
  24#include "dat.h"
  25
  26/**
  27 * nilfs_ioctl_wrap_copy - wrapping function of get/set metadata info
  28 * @nilfs: nilfs object
  29 * @argv: vector of arguments from userspace
  30 * @dir: set of direction flags
  31 * @dofunc: concrete function of get/set metadata info
  32 *
  33 * Description: nilfs_ioctl_wrap_copy() gets/sets metadata info by means of
  34 * calling dofunc() function on the basis of @argv argument.
  35 *
  36 * Return Value: On success, 0 is returned and requested metadata info
  37 * is copied into userspace. On error, one of the following
  38 * negative error codes is returned.
  39 *
  40 * %-EINVAL - Invalid arguments from userspace.
  41 *
  42 * %-ENOMEM - Insufficient amount of memory available.
  43 *
  44 * %-EFAULT - Failure during execution of requested operation.
  45 */
  46static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
  47                                 struct nilfs_argv *argv, int dir,
  48                                 ssize_t (*dofunc)(struct the_nilfs *,
  49                                                   __u64 *, int,
  50                                                   void *, size_t, size_t))
  51{
  52        void *buf;
  53        void __user *base = (void __user *)(unsigned long)argv->v_base;
  54        size_t maxmembs, total, n;
  55        ssize_t nr;
  56        int ret, i;
  57        __u64 pos, ppos;
  58
  59        if (argv->v_nmembs == 0)
  60                return 0;
  61
  62        if (argv->v_size > PAGE_SIZE)
  63                return -EINVAL;
  64
  65        /*
  66         * Reject pairs of a start item position (argv->v_index) and a
  67         * total count (argv->v_nmembs) which leads position 'pos' to
  68         * overflow by the increment at the end of the loop.
  69         */
  70        if (argv->v_index > ~(__u64)0 - argv->v_nmembs)
  71                return -EINVAL;
  72
  73        buf = (void *)__get_free_pages(GFP_NOFS, 0);
  74        if (unlikely(!buf))
  75                return -ENOMEM;
  76        maxmembs = PAGE_SIZE / argv->v_size;
  77
  78        ret = 0;
  79        total = 0;
  80        pos = argv->v_index;
  81        for (i = 0; i < argv->v_nmembs; i += n) {
  82                n = (argv->v_nmembs - i < maxmembs) ?
  83                        argv->v_nmembs - i : maxmembs;
  84                if ((dir & _IOC_WRITE) &&
  85                    copy_from_user(buf, base + argv->v_size * i,
  86                                   argv->v_size * n)) {
  87                        ret = -EFAULT;
  88                        break;
  89                }
  90                ppos = pos;
  91                nr = dofunc(nilfs, &pos, argv->v_flags, buf, argv->v_size,
  92                               n);
  93                if (nr < 0) {
  94                        ret = nr;
  95                        break;
  96                }
  97                if ((dir & _IOC_READ) &&
  98                    copy_to_user(base + argv->v_size * i, buf,
  99                                 argv->v_size * nr)) {
 100                        ret = -EFAULT;
 101                        break;
 102                }
 103                total += nr;
 104                if ((size_t)nr < n)
 105                        break;
 106                if (pos == ppos)
 107                        pos += n;
 108        }
 109        argv->v_nmembs = total;
 110
 111        free_pages((unsigned long)buf, 0);
 112        return ret;
 113}
 114
 115/**
 116 * nilfs_ioctl_getflags - ioctl to support lsattr
 117 */
 118static int nilfs_ioctl_getflags(struct inode *inode, void __user *argp)
 119{
 120        unsigned int flags = NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE;
 121
 122        return put_user(flags, (int __user *)argp);
 123}
 124
 125/**
 126 * nilfs_ioctl_setflags - ioctl to support chattr
 127 */
 128static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp,
 129                                void __user *argp)
 130{
 131        struct nilfs_transaction_info ti;
 132        unsigned int flags, oldflags;
 133        int ret;
 134
 135        if (!inode_owner_or_capable(inode))
 136                return -EACCES;
 137
 138        if (get_user(flags, (int __user *)argp))
 139                return -EFAULT;
 140
 141        ret = mnt_want_write_file(filp);
 142        if (ret)
 143                return ret;
 144
 145        flags = nilfs_mask_flags(inode->i_mode, flags);
 146
 147        inode_lock(inode);
 148
 149        oldflags = NILFS_I(inode)->i_flags;
 150
 151        /*
 152         * The IMMUTABLE and APPEND_ONLY flags can only be changed by the
 153         * relevant capability.
 154         */
 155        ret = -EPERM;
 156        if (((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) &&
 157            !capable(CAP_LINUX_IMMUTABLE))
 158                goto out;
 159
 160        ret = nilfs_transaction_begin(inode->i_sb, &ti, 0);
 161        if (ret)
 162                goto out;
 163
 164        NILFS_I(inode)->i_flags = (oldflags & ~FS_FL_USER_MODIFIABLE) |
 165                (flags & FS_FL_USER_MODIFIABLE);
 166
 167        nilfs_set_inode_flags(inode);
 168        inode->i_ctime = current_time(inode);
 169        if (IS_SYNC(inode))
 170                nilfs_set_transaction_flag(NILFS_TI_SYNC);
 171
 172        nilfs_mark_inode_dirty(inode);
 173        ret = nilfs_transaction_commit(inode->i_sb);
 174out:
 175        inode_unlock(inode);
 176        mnt_drop_write_file(filp);
 177        return ret;
 178}
 179
 180/**
 181 * nilfs_ioctl_getversion - get info about a file's version (generation number)
 182 */
 183static int nilfs_ioctl_getversion(struct inode *inode, void __user *argp)
 184{
 185        return put_user(inode->i_generation, (int __user *)argp);
 186}
 187
 188/**
 189 * nilfs_ioctl_change_cpmode - change checkpoint mode (checkpoint/snapshot)
 190 * @inode: inode object
 191 * @filp: file object
 192 * @cmd: ioctl's request code
 193 * @argp: pointer on argument from userspace
 194 *
 195 * Description: nilfs_ioctl_change_cpmode() function changes mode of
 196 * given checkpoint between checkpoint and snapshot state. This ioctl
 197 * is used in chcp and mkcp utilities.
 198 *
 199 * Return Value: On success, 0 is returned and mode of a checkpoint is
 200 * changed. On error, one of the following negative error codes
 201 * is returned.
 202 *
 203 * %-EPERM - Operation not permitted.
 204 *
 205 * %-EFAULT - Failure during checkpoint mode changing.
 206 */
 207static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
 208                                     unsigned int cmd, void __user *argp)
 209{
 210        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
 211        struct nilfs_transaction_info ti;
 212        struct nilfs_cpmode cpmode;
 213        int ret;
 214
 215        if (!capable(CAP_SYS_ADMIN))
 216                return -EPERM;
 217
 218        ret = mnt_want_write_file(filp);
 219        if (ret)
 220                return ret;
 221
 222        ret = -EFAULT;
 223        if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
 224                goto out;
 225
 226        mutex_lock(&nilfs->ns_snapshot_mount_mutex);
 227
 228        nilfs_transaction_begin(inode->i_sb, &ti, 0);
 229        ret = nilfs_cpfile_change_cpmode(
 230                nilfs->ns_cpfile, cpmode.cm_cno, cpmode.cm_mode);
 231        if (unlikely(ret < 0))
 232                nilfs_transaction_abort(inode->i_sb);
 233        else
 234                nilfs_transaction_commit(inode->i_sb); /* never fails */
 235
 236        mutex_unlock(&nilfs->ns_snapshot_mount_mutex);
 237out:
 238        mnt_drop_write_file(filp);
 239        return ret;
 240}
 241
 242/**
 243 * nilfs_ioctl_delete_checkpoint - remove checkpoint
 244 * @inode: inode object
 245 * @filp: file object
 246 * @cmd: ioctl's request code
 247 * @argp: pointer on argument from userspace
 248 *
 249 * Description: nilfs_ioctl_delete_checkpoint() function removes
 250 * checkpoint from NILFS2 file system. This ioctl is used in rmcp
 251 * utility.
 252 *
 253 * Return Value: On success, 0 is returned and a checkpoint is
 254 * removed. On error, one of the following negative error codes
 255 * is returned.
 256 *
 257 * %-EPERM - Operation not permitted.
 258 *
 259 * %-EFAULT - Failure during checkpoint removing.
 260 */
 261static int
 262nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
 263                              unsigned int cmd, void __user *argp)
 264{
 265        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
 266        struct nilfs_transaction_info ti;
 267        __u64 cno;
 268        int ret;
 269
 270        if (!capable(CAP_SYS_ADMIN))
 271                return -EPERM;
 272
 273        ret = mnt_want_write_file(filp);
 274        if (ret)
 275                return ret;
 276
 277        ret = -EFAULT;
 278        if (copy_from_user(&cno, argp, sizeof(cno)))
 279                goto out;
 280
 281        nilfs_transaction_begin(inode->i_sb, &ti, 0);
 282        ret = nilfs_cpfile_delete_checkpoint(nilfs->ns_cpfile, cno);
 283        if (unlikely(ret < 0))
 284                nilfs_transaction_abort(inode->i_sb);
 285        else
 286                nilfs_transaction_commit(inode->i_sb); /* never fails */
 287out:
 288        mnt_drop_write_file(filp);
 289        return ret;
 290}
 291
 292/**
 293 * nilfs_ioctl_do_get_cpinfo - callback method getting info about checkpoints
 294 * @nilfs: nilfs object
 295 * @posp: pointer on array of checkpoint's numbers
 296 * @flags: checkpoint mode (checkpoint or snapshot)
 297 * @buf: buffer for storing checkponts' info
 298 * @size: size in bytes of one checkpoint info item in array
 299 * @nmembs: number of checkpoints in array (numbers and infos)
 300 *
 301 * Description: nilfs_ioctl_do_get_cpinfo() function returns info about
 302 * requested checkpoints. The NILFS_IOCTL_GET_CPINFO ioctl is used in
 303 * lscp utility and by nilfs_cleanerd daemon.
 304 *
 305 * Return value: count of nilfs_cpinfo structures in output buffer.
 306 */
 307static ssize_t
 308nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
 309                          void *buf, size_t size, size_t nmembs)
 310{
 311        int ret;
 312
 313        down_read(&nilfs->ns_segctor_sem);
 314        ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
 315                                      size, nmembs);
 316        up_read(&nilfs->ns_segctor_sem);
 317        return ret;
 318}
 319
 320/**
 321 * nilfs_ioctl_get_cpstat - get checkpoints statistics
 322 * @inode: inode object
 323 * @filp: file object
 324 * @cmd: ioctl's request code
 325 * @argp: pointer on argument from userspace
 326 *
 327 * Description: nilfs_ioctl_get_cpstat() returns information about checkpoints.
 328 * The NILFS_IOCTL_GET_CPSTAT ioctl is used by lscp, rmcp utilities
 329 * and by nilfs_cleanerd daemon.
 330 *
 331 * Return Value: On success, 0 is returned, and checkpoints information is
 332 * copied into userspace pointer @argp. On error, one of the following
 333 * negative error codes is returned.
 334 *
 335 * %-EIO - I/O error.
 336 *
 337 * %-ENOMEM - Insufficient amount of memory available.
 338 *
 339 * %-EFAULT - Failure during getting checkpoints statistics.
 340 */
 341static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
 342                                  unsigned int cmd, void __user *argp)
 343{
 344        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
 345        struct nilfs_cpstat cpstat;
 346        int ret;
 347
 348        down_read(&nilfs->ns_segctor_sem);
 349        ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
 350        up_read(&nilfs->ns_segctor_sem);
 351        if (ret < 0)
 352                return ret;
 353
 354        if (copy_to_user(argp, &cpstat, sizeof(cpstat)))
 355                ret = -EFAULT;
 356        return ret;
 357}
 358
 359/**
 360 * nilfs_ioctl_do_get_suinfo - callback method getting segment usage info
 361 * @nilfs: nilfs object
 362 * @posp: pointer on array of segment numbers
 363 * @flags: *not used*
 364 * @buf: buffer for storing suinfo array
 365 * @size: size in bytes of one suinfo item in array
 366 * @nmembs: count of segment numbers and suinfos in array
 367 *
 368 * Description: nilfs_ioctl_do_get_suinfo() function returns segment usage
 369 * info about requested segments. The NILFS_IOCTL_GET_SUINFO ioctl is used
 370 * in lssu, nilfs_resize utilities and by nilfs_cleanerd daemon.
 371 *
 372 * Return value: count of nilfs_suinfo structures in output buffer.
 373 */
 374static ssize_t
 375nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
 376                          void *buf, size_t size, size_t nmembs)
 377{
 378        int ret;
 379
 380        down_read(&nilfs->ns_segctor_sem);
 381        ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size,
 382                                      nmembs);
 383        up_read(&nilfs->ns_segctor_sem);
 384        return ret;
 385}
 386
 387/**
 388 * nilfs_ioctl_get_sustat - get segment usage statistics
 389 * @inode: inode object
 390 * @filp: file object
 391 * @cmd: ioctl's request code
 392 * @argp: pointer on argument from userspace
 393 *
 394 * Description: nilfs_ioctl_get_sustat() returns segment usage statistics.
 395 * The NILFS_IOCTL_GET_SUSTAT ioctl is used in lssu, nilfs_resize utilities
 396 * and by nilfs_cleanerd daemon.
 397 *
 398 * Return Value: On success, 0 is returned, and segment usage information is
 399 * copied into userspace pointer @argp. On error, one of the following
 400 * negative error codes is returned.
 401 *
 402 * %-EIO - I/O error.
 403 *
 404 * %-ENOMEM - Insufficient amount of memory available.
 405 *
 406 * %-EFAULT - Failure during getting segment usage statistics.
 407 */
 408static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
 409                                  unsigned int cmd, void __user *argp)
 410{
 411        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
 412        struct nilfs_sustat sustat;
 413        int ret;
 414
 415        down_read(&nilfs->ns_segctor_sem);
 416        ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
 417        up_read(&nilfs->ns_segctor_sem);
 418        if (ret < 0)
 419                return ret;
 420
 421        if (copy_to_user(argp, &sustat, sizeof(sustat)))
 422                ret = -EFAULT;
 423        return ret;
 424}
 425
 426/**
 427 * nilfs_ioctl_do_get_vinfo - callback method getting virtual blocks info
 428 * @nilfs: nilfs object
 429 * @posp: *not used*
 430 * @flags: *not used*
 431 * @buf: buffer for storing array of nilfs_vinfo structures
 432 * @size: size in bytes of one vinfo item in array
 433 * @nmembs: count of vinfos in array
 434 *
 435 * Description: nilfs_ioctl_do_get_vinfo() function returns information
 436 * on virtual block addresses. The NILFS_IOCTL_GET_VINFO ioctl is used
 437 * by nilfs_cleanerd daemon.
 438 *
 439 * Return value: count of nilfs_vinfo structures in output buffer.
 440 */
 441static ssize_t
 442nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
 443                         void *buf, size_t size, size_t nmembs)
 444{
 445        int ret;
 446
 447        down_read(&nilfs->ns_segctor_sem);
 448        ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs);
 449        up_read(&nilfs->ns_segctor_sem);
 450        return ret;
 451}
 452
 453/**
 454 * nilfs_ioctl_do_get_bdescs - callback method getting disk block descriptors
 455 * @nilfs: nilfs object
 456 * @posp: *not used*
 457 * @flags: *not used*
 458 * @buf: buffer for storing array of nilfs_bdesc structures
 459 * @size: size in bytes of one bdesc item in array
 460 * @nmembs: count of bdescs in array
 461 *
 462 * Description: nilfs_ioctl_do_get_bdescs() function returns information
 463 * about descriptors of disk block numbers. The NILFS_IOCTL_GET_BDESCS ioctl
 464 * is used by nilfs_cleanerd daemon.
 465 *
 466 * Return value: count of nilfs_bdescs structures in output buffer.
 467 */
 468static ssize_t
 469nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
 470                          void *buf, size_t size, size_t nmembs)
 471{
 472        struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
 473        struct nilfs_bdesc *bdescs = buf;
 474        int ret, i;
 475
 476        down_read(&nilfs->ns_segctor_sem);
 477        for (i = 0; i < nmembs; i++) {
 478                ret = nilfs_bmap_lookup_at_level(bmap,
 479                                                 bdescs[i].bd_offset,
 480                                                 bdescs[i].bd_level + 1,
 481                                                 &bdescs[i].bd_blocknr);
 482                if (ret < 0) {
 483                        if (ret != -ENOENT) {
 484                                up_read(&nilfs->ns_segctor_sem);
 485                                return ret;
 486                        }
 487                        bdescs[i].bd_blocknr = 0;
 488                }
 489        }
 490        up_read(&nilfs->ns_segctor_sem);
 491        return nmembs;
 492}
 493
 494/**
 495 * nilfs_ioctl_get_bdescs - get disk block descriptors
 496 * @inode: inode object
 497 * @filp: file object
 498 * @cmd: ioctl's request code
 499 * @argp: pointer on argument from userspace
 500 *
 501 * Description: nilfs_ioctl_do_get_bdescs() function returns information
 502 * about descriptors of disk block numbers. The NILFS_IOCTL_GET_BDESCS ioctl
 503 * is used by nilfs_cleanerd daemon.
 504 *
 505 * Return Value: On success, 0 is returned, and disk block descriptors are
 506 * copied into userspace pointer @argp. On error, one of the following
 507 * negative error codes is returned.
 508 *
 509 * %-EINVAL - Invalid arguments from userspace.
 510 *
 511 * %-EIO - I/O error.
 512 *
 513 * %-ENOMEM - Insufficient amount of memory available.
 514 *
 515 * %-EFAULT - Failure during getting disk block descriptors.
 516 */
 517static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
 518                                  unsigned int cmd, void __user *argp)
 519{
 520        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
 521        struct nilfs_argv argv;
 522        int ret;
 523
 524        if (copy_from_user(&argv, argp, sizeof(argv)))
 525                return -EFAULT;
 526
 527        if (argv.v_size != sizeof(struct nilfs_bdesc))
 528                return -EINVAL;
 529
 530        ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
 531                                    nilfs_ioctl_do_get_bdescs);
 532        if (ret < 0)
 533                return ret;
 534
 535        if (copy_to_user(argp, &argv, sizeof(argv)))
 536                ret = -EFAULT;
 537        return ret;
 538}
 539
 540/**
 541 * nilfs_ioctl_move_inode_block - prepare data/node block for moving by GC
 542 * @inode: inode object
 543 * @vdesc: descriptor of virtual block number
 544 * @buffers: list of moving buffers
 545 *
 546 * Description: nilfs_ioctl_move_inode_block() function registers data/node
 547 * buffer in the GC pagecache and submit read request.
 548 *
 549 * Return Value: On success, 0 is returned. On error, one of the following
 550 * negative error codes is returned.
 551 *
 552 * %-EIO - I/O error.
 553 *
 554 * %-ENOMEM - Insufficient amount of memory available.
 555 *
 556 * %-ENOENT - Requested block doesn't exist.
 557 *
 558 * %-EEXIST - Blocks conflict is detected.
 559 */
 560static int nilfs_ioctl_move_inode_block(struct inode *inode,
 561                                        struct nilfs_vdesc *vdesc,
 562                                        struct list_head *buffers)
 563{
 564        struct buffer_head *bh;
 565        int ret;
 566
 567        if (vdesc->vd_flags == 0)
 568                ret = nilfs_gccache_submit_read_data(
 569                        inode, vdesc->vd_offset, vdesc->vd_blocknr,
 570                        vdesc->vd_vblocknr, &bh);
 571        else
 572                ret = nilfs_gccache_submit_read_node(
 573                        inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh);
 574
 575        if (unlikely(ret < 0)) {
 576                if (ret == -ENOENT)
 577                        nilfs_msg(inode->i_sb, KERN_CRIT,
 578                                  "%s: invalid virtual block address (%s): ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
 579                                  __func__, vdesc->vd_flags ? "node" : "data",
 580                                  (unsigned long long)vdesc->vd_ino,
 581                                  (unsigned long long)vdesc->vd_cno,
 582                                  (unsigned long long)vdesc->vd_offset,
 583                                  (unsigned long long)vdesc->vd_blocknr,
 584                                  (unsigned long long)vdesc->vd_vblocknr);
 585                return ret;
 586        }
 587        if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
 588                nilfs_msg(inode->i_sb, KERN_CRIT,
 589                          "%s: conflicting %s buffer: ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
 590                          __func__, vdesc->vd_flags ? "node" : "data",
 591                          (unsigned long long)vdesc->vd_ino,
 592                          (unsigned long long)vdesc->vd_cno,
 593                          (unsigned long long)vdesc->vd_offset,
 594                          (unsigned long long)vdesc->vd_blocknr,
 595                          (unsigned long long)vdesc->vd_vblocknr);
 596                brelse(bh);
 597                return -EEXIST;
 598        }
 599        list_add_tail(&bh->b_assoc_buffers, buffers);
 600        return 0;
 601}
 602
 603/**
 604 * nilfs_ioctl_move_blocks - move valid inode's blocks during garbage collection
 605 * @sb: superblock object
 606 * @argv: vector of arguments from userspace
 607 * @buf: array of nilfs_vdesc structures
 608 *
 609 * Description: nilfs_ioctl_move_blocks() function reads valid data/node
 610 * blocks that garbage collector specified with the array of nilfs_vdesc
 611 * structures and stores them into page caches of GC inodes.
 612 *
 613 * Return Value: Number of processed nilfs_vdesc structures or
 614 * error code, otherwise.
 615 */
 616static int nilfs_ioctl_move_blocks(struct super_block *sb,
 617                                   struct nilfs_argv *argv, void *buf)
 618{
 619        size_t nmembs = argv->v_nmembs;
 620        struct the_nilfs *nilfs = sb->s_fs_info;
 621        struct inode *inode;
 622        struct nilfs_vdesc *vdesc;
 623        struct buffer_head *bh, *n;
 624        LIST_HEAD(buffers);
 625        ino_t ino;
 626        __u64 cno;
 627        int i, ret;
 628
 629        for (i = 0, vdesc = buf; i < nmembs; ) {
 630                ino = vdesc->vd_ino;
 631                cno = vdesc->vd_cno;
 632                inode = nilfs_iget_for_gc(sb, ino, cno);
 633                if (IS_ERR(inode)) {
 634                        ret = PTR_ERR(inode);
 635                        goto failed;
 636                }
 637                if (list_empty(&NILFS_I(inode)->i_dirty)) {
 638                        /*
 639                         * Add the inode to GC inode list. Garbage Collection
 640                         * is serialized and no two processes manipulate the
 641                         * list simultaneously.
 642                         */
 643                        igrab(inode);
 644                        list_add(&NILFS_I(inode)->i_dirty,
 645                                 &nilfs->ns_gc_inodes);
 646                }
 647
 648                do {
 649                        ret = nilfs_ioctl_move_inode_block(inode, vdesc,
 650                                                           &buffers);
 651                        if (unlikely(ret < 0)) {
 652                                iput(inode);
 653                                goto failed;
 654                        }
 655                        vdesc++;
 656                } while (++i < nmembs &&
 657                         vdesc->vd_ino == ino && vdesc->vd_cno == cno);
 658
 659                iput(inode); /* The inode still remains in GC inode list */
 660        }
 661
 662        list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
 663                ret = nilfs_gccache_wait_and_mark_dirty(bh);
 664                if (unlikely(ret < 0)) {
 665                        WARN_ON(ret == -EEXIST);
 666                        goto failed;
 667                }
 668                list_del_init(&bh->b_assoc_buffers);
 669                brelse(bh);
 670        }
 671        return nmembs;
 672
 673 failed:
 674        list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
 675                list_del_init(&bh->b_assoc_buffers);
 676                brelse(bh);
 677        }
 678        return ret;
 679}
 680
 681/**
 682 * nilfs_ioctl_delete_checkpoints - delete checkpoints
 683 * @nilfs: nilfs object
 684 * @argv: vector of arguments from userspace
 685 * @buf: array of periods of checkpoints numbers
 686 *
 687 * Description: nilfs_ioctl_delete_checkpoints() function deletes checkpoints
 688 * in the period from p_start to p_end, excluding p_end itself. The checkpoints
 689 * which have been already deleted are ignored.
 690 *
 691 * Return Value: Number of processed nilfs_period structures or
 692 * error code, otherwise.
 693 *
 694 * %-EIO - I/O error.
 695 *
 696 * %-ENOMEM - Insufficient amount of memory available.
 697 *
 698 * %-EINVAL - invalid checkpoints.
 699 */
 700static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
 701                                          struct nilfs_argv *argv, void *buf)
 702{
 703        size_t nmembs = argv->v_nmembs;
 704        struct inode *cpfile = nilfs->ns_cpfile;
 705        struct nilfs_period *periods = buf;
 706        int ret, i;
 707
 708        for (i = 0; i < nmembs; i++) {
 709                ret = nilfs_cpfile_delete_checkpoints(
 710                        cpfile, periods[i].p_start, periods[i].p_end);
 711                if (ret < 0)
 712                        return ret;
 713        }
 714        return nmembs;
 715}
 716
 717/**
 718 * nilfs_ioctl_free_vblocknrs - free virtual block numbers
 719 * @nilfs: nilfs object
 720 * @argv: vector of arguments from userspace
 721 * @buf: array of virtual block numbers
 722 *
 723 * Description: nilfs_ioctl_free_vblocknrs() function frees
 724 * the virtual block numbers specified by @buf and @argv->v_nmembs.
 725 *
 726 * Return Value: Number of processed virtual block numbers or
 727 * error code, otherwise.
 728 *
 729 * %-EIO - I/O error.
 730 *
 731 * %-ENOMEM - Insufficient amount of memory available.
 732 *
 733 * %-ENOENT - The virtual block number have not been allocated.
 734 */
 735static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
 736                                      struct nilfs_argv *argv, void *buf)
 737{
 738        size_t nmembs = argv->v_nmembs;
 739        int ret;
 740
 741        ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs);
 742
 743        return (ret < 0) ? ret : nmembs;
 744}
 745
 746/**
 747 * nilfs_ioctl_mark_blocks_dirty - mark blocks dirty
 748 * @nilfs: nilfs object
 749 * @argv: vector of arguments from userspace
 750 * @buf: array of block descriptors
 751 *
 752 * Description: nilfs_ioctl_mark_blocks_dirty() function marks
 753 * metadata file or data blocks as dirty.
 754 *
 755 * Return Value: Number of processed block descriptors or
 756 * error code, otherwise.
 757 *
 758 * %-ENOMEM - Insufficient memory available.
 759 *
 760 * %-EIO - I/O error
 761 *
 762 * %-ENOENT - the specified block does not exist (hole block)
 763 */
 764static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
 765                                         struct nilfs_argv *argv, void *buf)
 766{
 767        size_t nmembs = argv->v_nmembs;
 768        struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
 769        struct nilfs_bdesc *bdescs = buf;
 770        struct buffer_head *bh;
 771        int ret, i;
 772
 773        for (i = 0; i < nmembs; i++) {
 774                /* XXX: use macro or inline func to check liveness */
 775                ret = nilfs_bmap_lookup_at_level(bmap,
 776                                                 bdescs[i].bd_offset,
 777                                                 bdescs[i].bd_level + 1,
 778                                                 &bdescs[i].bd_blocknr);
 779                if (ret < 0) {
 780                        if (ret != -ENOENT)
 781                                return ret;
 782                        bdescs[i].bd_blocknr = 0;
 783                }
 784                if (bdescs[i].bd_blocknr != bdescs[i].bd_oblocknr)
 785                        /* skip dead block */
 786                        continue;
 787                if (bdescs[i].bd_level == 0) {
 788                        ret = nilfs_mdt_get_block(nilfs->ns_dat,
 789                                                  bdescs[i].bd_offset,
 790                                                  false, NULL, &bh);
 791                        if (unlikely(ret)) {
 792                                WARN_ON(ret == -ENOENT);
 793                                return ret;
 794                        }
 795                        mark_buffer_dirty(bh);
 796                        nilfs_mdt_mark_dirty(nilfs->ns_dat);
 797                        put_bh(bh);
 798                } else {
 799                        ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset,
 800                                              bdescs[i].bd_level);
 801                        if (ret < 0) {
 802                                WARN_ON(ret == -ENOENT);
 803                                return ret;
 804                        }
 805                }
 806        }
 807        return nmembs;
 808}
 809
 810int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
 811                                       struct nilfs_argv *argv, void **kbufs)
 812{
 813        const char *msg;
 814        int ret;
 815
 816        ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
 817        if (ret < 0) {
 818                /*
 819                 * can safely abort because checkpoints can be removed
 820                 * independently.
 821                 */
 822                msg = "cannot delete checkpoints";
 823                goto failed;
 824        }
 825        ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
 826        if (ret < 0) {
 827                /*
 828                 * can safely abort because DAT file is updated atomically
 829                 * using a copy-on-write technique.
 830                 */
 831                msg = "cannot delete virtual blocks from DAT file";
 832                goto failed;
 833        }
 834        ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
 835        if (ret < 0) {
 836                /*
 837                 * can safely abort because the operation is nondestructive.
 838                 */
 839                msg = "cannot mark copying blocks dirty";
 840                goto failed;
 841        }
 842        return 0;
 843
 844 failed:
 845        nilfs_msg(nilfs->ns_sb, KERN_ERR, "error %d preparing GC: %s", ret,
 846                  msg);
 847        return ret;
 848}
 849
 850/**
 851 * nilfs_ioctl_clean_segments - clean segments
 852 * @inode: inode object
 853 * @filp: file object
 854 * @cmd: ioctl's request code
 855 * @argp: pointer on argument from userspace
 856 *
 857 * Description: nilfs_ioctl_clean_segments() function makes garbage
 858 * collection operation in the environment of requested parameters
 859 * from userspace. The NILFS_IOCTL_CLEAN_SEGMENTS ioctl is used by
 860 * nilfs_cleanerd daemon.
 861 *
 862 * Return Value: On success, 0 is returned or error code, otherwise.
 863 */
 864static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
 865                                      unsigned int cmd, void __user *argp)
 866{
 867        struct nilfs_argv argv[5];
 868        static const size_t argsz[5] = {
 869                sizeof(struct nilfs_vdesc),
 870                sizeof(struct nilfs_period),
 871                sizeof(__u64),
 872                sizeof(struct nilfs_bdesc),
 873                sizeof(__u64),
 874        };
 875        void __user *base;
 876        void *kbufs[5];
 877        struct the_nilfs *nilfs;
 878        size_t len, nsegs;
 879        int n, ret;
 880
 881        if (!capable(CAP_SYS_ADMIN))
 882                return -EPERM;
 883
 884        ret = mnt_want_write_file(filp);
 885        if (ret)
 886                return ret;
 887
 888        ret = -EFAULT;
 889        if (copy_from_user(argv, argp, sizeof(argv)))
 890                goto out;
 891
 892        ret = -EINVAL;
 893        nsegs = argv[4].v_nmembs;
 894        if (argv[4].v_size != argsz[4])
 895                goto out;
 896        if (nsegs > UINT_MAX / sizeof(__u64))
 897                goto out;
 898
 899        /*
 900         * argv[4] points to segment numbers this ioctl cleans.  We
 901         * use kmalloc() for its buffer because memory used for the
 902         * segment numbers is enough small.
 903         */
 904        kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
 905                               nsegs * sizeof(__u64));
 906        if (IS_ERR(kbufs[4])) {
 907                ret = PTR_ERR(kbufs[4]);
 908                goto out;
 909        }
 910        nilfs = inode->i_sb->s_fs_info;
 911
 912        for (n = 0; n < 4; n++) {
 913                ret = -EINVAL;
 914                if (argv[n].v_size != argsz[n])
 915                        goto out_free;
 916
 917                if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
 918                        goto out_free;
 919
 920                if (argv[n].v_nmembs >= UINT_MAX / argv[n].v_size)
 921                        goto out_free;
 922
 923                len = argv[n].v_size * argv[n].v_nmembs;
 924                base = (void __user *)(unsigned long)argv[n].v_base;
 925                if (len == 0) {
 926                        kbufs[n] = NULL;
 927                        continue;
 928                }
 929
 930                kbufs[n] = vmalloc(len);
 931                if (!kbufs[n]) {
 932                        ret = -ENOMEM;
 933                        goto out_free;
 934                }
 935                if (copy_from_user(kbufs[n], base, len)) {
 936                        ret = -EFAULT;
 937                        vfree(kbufs[n]);
 938                        goto out_free;
 939                }
 940        }
 941
 942        /*
 943         * nilfs_ioctl_move_blocks() will call nilfs_iget_for_gc(),
 944         * which will operates an inode list without blocking.
 945         * To protect the list from concurrent operations,
 946         * nilfs_ioctl_move_blocks should be atomic operation.
 947         */
 948        if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) {
 949                ret = -EBUSY;
 950                goto out_free;
 951        }
 952
 953        ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
 954        if (ret < 0) {
 955                nilfs_msg(inode->i_sb, KERN_ERR,
 956                          "error %d preparing GC: cannot read source blocks",
 957                          ret);
 958        } else {
 959                if (nilfs_sb_need_update(nilfs))
 960                        set_nilfs_discontinued(nilfs);
 961                ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
 962        }
 963
 964        nilfs_remove_all_gcinodes(nilfs);
 965        clear_nilfs_gc_running(nilfs);
 966
 967out_free:
 968        while (--n >= 0)
 969                vfree(kbufs[n]);
 970        kfree(kbufs[4]);
 971out:
 972        mnt_drop_write_file(filp);
 973        return ret;
 974}
 975
 976/**
 977 * nilfs_ioctl_sync - make a checkpoint
 978 * @inode: inode object
 979 * @filp: file object
 980 * @cmd: ioctl's request code
 981 * @argp: pointer on argument from userspace
 982 *
 983 * Description: nilfs_ioctl_sync() function constructs a logical segment
 984 * for checkpointing.  This function guarantees that all modified data
 985 * and metadata are written out to the device when it successfully
 986 * returned.
 987 *
 988 * Return Value: On success, 0 is retured. On errors, one of the following
 989 * negative error code is returned.
 990 *
 991 * %-EROFS - Read only filesystem.
 992 *
 993 * %-EIO - I/O error
 994 *
 995 * %-ENOSPC - No space left on device (only in a panic state).
 996 *
 997 * %-ERESTARTSYS - Interrupted.
 998 *
 999 * %-ENOMEM - Insufficient memory available.
1000 *
1001 * %-EFAULT - Failure during execution of requested operation.
1002 */
1003static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
1004                            unsigned int cmd, void __user *argp)
1005{
1006        __u64 cno;
1007        int ret;
1008        struct the_nilfs *nilfs;
1009
1010        ret = nilfs_construct_segment(inode->i_sb);
1011        if (ret < 0)
1012                return ret;
1013
1014        nilfs = inode->i_sb->s_fs_info;
1015        ret = nilfs_flush_device(nilfs);
1016        if (ret < 0)
1017                return ret;
1018
1019        if (argp != NULL) {
1020                down_read(&nilfs->ns_segctor_sem);
1021                cno = nilfs->ns_cno - 1;
1022                up_read(&nilfs->ns_segctor_sem);
1023                if (copy_to_user(argp, &cno, sizeof(cno)))
1024                        return -EFAULT;
1025        }
1026        return 0;
1027}
1028
1029/**
1030 * nilfs_ioctl_resize - resize NILFS2 volume
1031 * @inode: inode object
1032 * @filp: file object
1033 * @argp: pointer on argument from userspace
1034 *
1035 * Return Value: On success, 0 is returned or error code, otherwise.
1036 */
1037static int nilfs_ioctl_resize(struct inode *inode, struct file *filp,
1038                              void __user *argp)
1039{
1040        __u64 newsize;
1041        int ret = -EPERM;
1042
1043        if (!capable(CAP_SYS_ADMIN))
1044                goto out;
1045
1046        ret = mnt_want_write_file(filp);
1047        if (ret)
1048                goto out;
1049
1050        ret = -EFAULT;
1051        if (copy_from_user(&newsize, argp, sizeof(newsize)))
1052                goto out_drop_write;
1053
1054        ret = nilfs_resize_fs(inode->i_sb, newsize);
1055
1056out_drop_write:
1057        mnt_drop_write_file(filp);
1058out:
1059        return ret;
1060}
1061
1062/**
1063 * nilfs_ioctl_trim_fs() - trim ioctl handle function
1064 * @inode: inode object
1065 * @argp: pointer on argument from userspace
1066 *
1067 * Decription: nilfs_ioctl_trim_fs is the FITRIM ioctl handle function. It
1068 * checks the arguments from userspace and calls nilfs_sufile_trim_fs, which
1069 * performs the actual trim operation.
1070 *
1071 * Return Value: On success, 0 is returned or negative error code, otherwise.
1072 */
1073static int nilfs_ioctl_trim_fs(struct inode *inode, void __user *argp)
1074{
1075        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1076        struct request_queue *q = bdev_get_queue(nilfs->ns_bdev);
1077        struct fstrim_range range;
1078        int ret;
1079
1080        if (!capable(CAP_SYS_ADMIN))
1081                return -EPERM;
1082
1083        if (!blk_queue_discard(q))
1084                return -EOPNOTSUPP;
1085
1086        if (copy_from_user(&range, argp, sizeof(range)))
1087                return -EFAULT;
1088
1089        range.minlen = max_t(u64, range.minlen, q->limits.discard_granularity);
1090
1091        down_read(&nilfs->ns_segctor_sem);
1092        ret = nilfs_sufile_trim_fs(nilfs->ns_sufile, &range);
1093        up_read(&nilfs->ns_segctor_sem);
1094
1095        if (ret < 0)
1096                return ret;
1097
1098        if (copy_to_user(argp, &range, sizeof(range)))
1099                return -EFAULT;
1100
1101        return 0;
1102}
1103
1104/**
1105 * nilfs_ioctl_set_alloc_range - limit range of segments to be allocated
1106 * @inode: inode object
1107 * @argp: pointer on argument from userspace
1108 *
1109 * Decription: nilfs_ioctl_set_alloc_range() function defines lower limit
1110 * of segments in bytes and upper limit of segments in bytes.
1111 * The NILFS_IOCTL_SET_ALLOC_RANGE is used by nilfs_resize utility.
1112 *
1113 * Return Value: On success, 0 is returned or error code, otherwise.
1114 */
1115static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp)
1116{
1117        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1118        __u64 range[2];
1119        __u64 minseg, maxseg;
1120        unsigned long segbytes;
1121        int ret = -EPERM;
1122
1123        if (!capable(CAP_SYS_ADMIN))
1124                goto out;
1125
1126        ret = -EFAULT;
1127        if (copy_from_user(range, argp, sizeof(__u64[2])))
1128                goto out;
1129
1130        ret = -ERANGE;
1131        if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode))
1132                goto out;
1133
1134        segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize;
1135
1136        minseg = range[0] + segbytes - 1;
1137        do_div(minseg, segbytes);
1138        maxseg = NILFS_SB2_OFFSET_BYTES(range[1]);
1139        do_div(maxseg, segbytes);
1140        maxseg--;
1141
1142        ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg);
1143out:
1144        return ret;
1145}
1146
1147/**
1148 * nilfs_ioctl_get_info - wrapping function of get metadata info
1149 * @inode: inode object
1150 * @filp: file object
1151 * @cmd: ioctl's request code
1152 * @argp: pointer on argument from userspace
1153 * @membsz: size of an item in bytes
1154 * @dofunc: concrete function of getting metadata info
1155 *
1156 * Description: nilfs_ioctl_get_info() gets metadata info by means of
1157 * calling dofunc() function.
1158 *
1159 * Return Value: On success, 0 is returned and requested metadata info
1160 * is copied into userspace. On error, one of the following
1161 * negative error codes is returned.
1162 *
1163 * %-EINVAL - Invalid arguments from userspace.
1164 *
1165 * %-ENOMEM - Insufficient amount of memory available.
1166 *
1167 * %-EFAULT - Failure during execution of requested operation.
1168 */
1169static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
1170                                unsigned int cmd, void __user *argp,
1171                                size_t membsz,
1172                                ssize_t (*dofunc)(struct the_nilfs *,
1173                                                  __u64 *, int,
1174                                                  void *, size_t, size_t))
1175
1176{
1177        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1178        struct nilfs_argv argv;
1179        int ret;
1180
1181        if (copy_from_user(&argv, argp, sizeof(argv)))
1182                return -EFAULT;
1183
1184        if (argv.v_size < membsz)
1185                return -EINVAL;
1186
1187        ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
1188        if (ret < 0)
1189                return ret;
1190
1191        if (copy_to_user(argp, &argv, sizeof(argv)))
1192                ret = -EFAULT;
1193        return ret;
1194}
1195
1196/**
1197 * nilfs_ioctl_set_suinfo - set segment usage info
1198 * @inode: inode object
1199 * @filp: file object
1200 * @cmd: ioctl's request code
1201 * @argp: pointer on argument from userspace
1202 *
1203 * Description: Expects an array of nilfs_suinfo_update structures
1204 * encapsulated in nilfs_argv and updates the segment usage info
1205 * according to the flags in nilfs_suinfo_update.
1206 *
1207 * Return Value: On success, 0 is returned. On error, one of the
1208 * following negative error codes is returned.
1209 *
1210 * %-EPERM - Not enough permissions
1211 *
1212 * %-EFAULT - Error copying input data
1213 *
1214 * %-EIO - I/O error.
1215 *
1216 * %-ENOMEM - Insufficient amount of memory available.
1217 *
1218 * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
1219 */
1220static int nilfs_ioctl_set_suinfo(struct inode *inode, struct file *filp,
1221                                unsigned int cmd, void __user *argp)
1222{
1223        struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
1224        struct nilfs_transaction_info ti;
1225        struct nilfs_argv argv;
1226        size_t len;
1227        void __user *base;
1228        void *kbuf;
1229        int ret;
1230
1231        if (!capable(CAP_SYS_ADMIN))
1232                return -EPERM;
1233
1234        ret = mnt_want_write_file(filp);
1235        if (ret)
1236                return ret;
1237
1238        ret = -EFAULT;
1239        if (copy_from_user(&argv, argp, sizeof(argv)))
1240                goto out;
1241
1242        ret = -EINVAL;
1243        if (argv.v_size < sizeof(struct nilfs_suinfo_update))
1244                goto out;
1245
1246        if (argv.v_nmembs > nilfs->ns_nsegments)
1247                goto out;
1248
1249        if (argv.v_nmembs >= UINT_MAX / argv.v_size)
1250                goto out;
1251
1252        len = argv.v_size * argv.v_nmembs;
1253        if (!len) {
1254                ret = 0;
1255                goto out;
1256        }
1257
1258        base = (void __user *)(unsigned long)argv.v_base;
1259        kbuf = vmalloc(len);
1260        if (!kbuf) {
1261                ret = -ENOMEM;
1262                goto out;
1263        }
1264
1265        if (copy_from_user(kbuf, base, len)) {
1266                ret = -EFAULT;
1267                goto out_free;
1268        }
1269
1270        nilfs_transaction_begin(inode->i_sb, &ti, 0);
1271        ret = nilfs_sufile_set_suinfo(nilfs->ns_sufile, kbuf, argv.v_size,
1272                        argv.v_nmembs);
1273        if (unlikely(ret < 0))
1274                nilfs_transaction_abort(inode->i_sb);
1275        else
1276                nilfs_transaction_commit(inode->i_sb); /* never fails */
1277
1278out_free:
1279        vfree(kbuf);
1280out:
1281        mnt_drop_write_file(filp);
1282        return ret;
1283}
1284
1285long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1286{
1287        struct inode *inode = file_inode(filp);
1288        void __user *argp = (void __user *)arg;
1289
1290        switch (cmd) {
1291        case FS_IOC_GETFLAGS:
1292                return nilfs_ioctl_getflags(inode, argp);
1293        case FS_IOC_SETFLAGS:
1294                return nilfs_ioctl_setflags(inode, filp, argp);
1295        case FS_IOC_GETVERSION:
1296                return nilfs_ioctl_getversion(inode, argp);
1297        case NILFS_IOCTL_CHANGE_CPMODE:
1298                return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp);
1299        case NILFS_IOCTL_DELETE_CHECKPOINT:
1300                return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
1301        case NILFS_IOCTL_GET_CPINFO:
1302                return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1303                                            sizeof(struct nilfs_cpinfo),
1304                                            nilfs_ioctl_do_get_cpinfo);
1305        case NILFS_IOCTL_GET_CPSTAT:
1306                return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
1307        case NILFS_IOCTL_GET_SUINFO:
1308                return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1309                                            sizeof(struct nilfs_suinfo),
1310                                            nilfs_ioctl_do_get_suinfo);
1311        case NILFS_IOCTL_SET_SUINFO:
1312                return nilfs_ioctl_set_suinfo(inode, filp, cmd, argp);
1313        case NILFS_IOCTL_GET_SUSTAT:
1314                return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
1315        case NILFS_IOCTL_GET_VINFO:
1316                return nilfs_ioctl_get_info(inode, filp, cmd, argp,
1317                                            sizeof(struct nilfs_vinfo),
1318                                            nilfs_ioctl_do_get_vinfo);
1319        case NILFS_IOCTL_GET_BDESCS:
1320                return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
1321        case NILFS_IOCTL_CLEAN_SEGMENTS:
1322                return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);
1323        case NILFS_IOCTL_SYNC:
1324                return nilfs_ioctl_sync(inode, filp, cmd, argp);
1325        case NILFS_IOCTL_RESIZE:
1326                return nilfs_ioctl_resize(inode, filp, argp);
1327        case NILFS_IOCTL_SET_ALLOC_RANGE:
1328                return nilfs_ioctl_set_alloc_range(inode, argp);
1329        case FITRIM:
1330                return nilfs_ioctl_trim_fs(inode, argp);
1331        default:
1332                return -ENOTTY;
1333        }
1334}
1335
1336#ifdef CONFIG_COMPAT
1337long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1338{
1339        switch (cmd) {
1340        case FS_IOC32_GETFLAGS:
1341                cmd = FS_IOC_GETFLAGS;
1342                break;
1343        case FS_IOC32_SETFLAGS:
1344                cmd = FS_IOC_SETFLAGS;
1345                break;
1346        case FS_IOC32_GETVERSION:
1347                cmd = FS_IOC_GETVERSION;
1348                break;
1349        case NILFS_IOCTL_CHANGE_CPMODE:
1350        case NILFS_IOCTL_DELETE_CHECKPOINT:
1351        case NILFS_IOCTL_GET_CPINFO:
1352        case NILFS_IOCTL_GET_CPSTAT:
1353        case NILFS_IOCTL_GET_SUINFO:
1354        case NILFS_IOCTL_SET_SUINFO:
1355        case NILFS_IOCTL_GET_SUSTAT:
1356        case NILFS_IOCTL_GET_VINFO:
1357        case NILFS_IOCTL_GET_BDESCS:
1358        case NILFS_IOCTL_CLEAN_SEGMENTS:
1359        case NILFS_IOCTL_SYNC:
1360        case NILFS_IOCTL_RESIZE:
1361        case NILFS_IOCTL_SET_ALLOC_RANGE:
1362                break;
1363        default:
1364                return -ENOIOCTLCMD;
1365        }
1366        return nilfs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
1367}
1368#endif
1369