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