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 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 * 20 * Written by Koji Sato <koji@osrg.net>. 21 */ 22 23 #include <linux/fs.h> 24 #include <linux/wait.h> 25 #include <linux/slab.h> 26 #include <linux/capability.h> /* capable() */ 27 #include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */ 28 #include <linux/vmalloc.h> 29 #include <linux/compat.h> /* compat_ptr() */ 30 #include <linux/mount.h> /* mnt_want_write_file(), mnt_drop_write_file() */ 31 #include <linux/buffer_head.h> 32 #include <linux/nilfs2_fs.h> 33 #include "nilfs.h" 34 #include "segment.h" 35 #include "bmap.h" 36 #include "cpfile.h" 37 #include "sufile.h" 38 #include "dat.h" 39 40 41 static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs, 42 struct nilfs_argv *argv, int dir, 43 ssize_t (*dofunc)(struct the_nilfs *, 44 __u64 *, int, 45 void *, size_t, size_t)) 46 { 47 void *buf; 48 void __user *base = (void __user *)(unsigned long)argv->v_base; 49 size_t maxmembs, total, n; 50 ssize_t nr; 51 int ret, i; 52 __u64 pos, ppos; 53 54 if (argv->v_nmembs == 0) 55 return 0; 56 57 if (argv->v_size > PAGE_SIZE) 58 return -EINVAL; 59 60 buf = (void *)__get_free_pages(GFP_NOFS, 0); 61 if (unlikely(!buf)) 62 return -ENOMEM; 63 maxmembs = PAGE_SIZE / argv->v_size; 64 65 ret = 0; 66 total = 0; 67 pos = argv->v_index; 68 for (i = 0; i < argv->v_nmembs; i += n) { 69 n = (argv->v_nmembs - i < maxmembs) ? 70 argv->v_nmembs - i : maxmembs; 71 if ((dir & _IOC_WRITE) && 72 copy_from_user(buf, base + argv->v_size * i, 73 argv->v_size * n)) { 74 ret = -EFAULT; 75 break; 76 } 77 ppos = pos; 78 nr = dofunc(nilfs, &pos, argv->v_flags, buf, argv->v_size, 79 n); 80 if (nr < 0) { 81 ret = nr; 82 break; 83 } 84 if ((dir & _IOC_READ) && 85 copy_to_user(base + argv->v_size * i, buf, 86 argv->v_size * nr)) { 87 ret = -EFAULT; 88 break; 89 } 90 total += nr; 91 if ((size_t)nr < n) 92 break; 93 if (pos == ppos) 94 pos += n; 95 } 96 argv->v_nmembs = total; 97 98 free_pages((unsigned long)buf, 0); 99 return ret; 100 } 101 102 static int nilfs_ioctl_getflags(struct inode *inode, void __user *argp) 103 { 104 unsigned int flags = NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE; 105 106 return put_user(flags, (int __user *)argp); 107 } 108 109 static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp, 110 void __user *argp) 111 { 112 struct nilfs_transaction_info ti; 113 unsigned int flags, oldflags; 114 int ret; 115 116 if (!inode_owner_or_capable(inode)) 117 return -EACCES; 118 119 if (get_user(flags, (int __user *)argp)) 120 return -EFAULT; 121 122 ret = mnt_want_write_file(filp); 123 if (ret) 124 return ret; 125 126 flags = nilfs_mask_flags(inode->i_mode, flags); 127 128 mutex_lock(&inode->i_mutex); 129 130 oldflags = NILFS_I(inode)->i_flags; 131 132 /* 133 * The IMMUTABLE and APPEND_ONLY flags can only be changed by the 134 * relevant capability. 135 */ 136 ret = -EPERM; 137 if (((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) && 138 !capable(CAP_LINUX_IMMUTABLE)) 139 goto out; 140 141 ret = nilfs_transaction_begin(inode->i_sb, &ti, 0); 142 if (ret) 143 goto out; 144 145 NILFS_I(inode)->i_flags = (oldflags & ~FS_FL_USER_MODIFIABLE) | 146 (flags & FS_FL_USER_MODIFIABLE); 147 148 nilfs_set_inode_flags(inode); 149 inode->i_ctime = CURRENT_TIME; 150 if (IS_SYNC(inode)) 151 nilfs_set_transaction_flag(NILFS_TI_SYNC); 152 153 nilfs_mark_inode_dirty(inode); 154 ret = nilfs_transaction_commit(inode->i_sb); 155 out: 156 mutex_unlock(&inode->i_mutex); 157 mnt_drop_write_file(filp); 158 return ret; 159 } 160 161 static int nilfs_ioctl_getversion(struct inode *inode, void __user *argp) 162 { 163 return put_user(inode->i_generation, (int __user *)argp); 164 } 165 166 static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp, 167 unsigned int cmd, void __user *argp) 168 { 169 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 170 struct nilfs_transaction_info ti; 171 struct nilfs_cpmode cpmode; 172 int ret; 173 174 if (!capable(CAP_SYS_ADMIN)) 175 return -EPERM; 176 177 ret = mnt_want_write_file(filp); 178 if (ret) 179 return ret; 180 181 ret = -EFAULT; 182 if (copy_from_user(&cpmode, argp, sizeof(cpmode))) 183 goto out; 184 185 mutex_lock(&nilfs->ns_snapshot_mount_mutex); 186 187 nilfs_transaction_begin(inode->i_sb, &ti, 0); 188 ret = nilfs_cpfile_change_cpmode( 189 nilfs->ns_cpfile, cpmode.cm_cno, cpmode.cm_mode); 190 if (unlikely(ret < 0)) 191 nilfs_transaction_abort(inode->i_sb); 192 else 193 nilfs_transaction_commit(inode->i_sb); /* never fails */ 194 195 mutex_unlock(&nilfs->ns_snapshot_mount_mutex); 196 out: 197 mnt_drop_write_file(filp); 198 return ret; 199 } 200 201 static int 202 nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp, 203 unsigned int cmd, void __user *argp) 204 { 205 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 206 struct nilfs_transaction_info ti; 207 __u64 cno; 208 int ret; 209 210 if (!capable(CAP_SYS_ADMIN)) 211 return -EPERM; 212 213 ret = mnt_want_write_file(filp); 214 if (ret) 215 return ret; 216 217 ret = -EFAULT; 218 if (copy_from_user(&cno, argp, sizeof(cno))) 219 goto out; 220 221 nilfs_transaction_begin(inode->i_sb, &ti, 0); 222 ret = nilfs_cpfile_delete_checkpoint(nilfs->ns_cpfile, cno); 223 if (unlikely(ret < 0)) 224 nilfs_transaction_abort(inode->i_sb); 225 else 226 nilfs_transaction_commit(inode->i_sb); /* never fails */ 227 out: 228 mnt_drop_write_file(filp); 229 return ret; 230 } 231 232 static ssize_t 233 nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, 234 void *buf, size_t size, size_t nmembs) 235 { 236 int ret; 237 238 down_read(&nilfs->ns_segctor_sem); 239 ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf, 240 size, nmembs); 241 up_read(&nilfs->ns_segctor_sem); 242 return ret; 243 } 244 245 static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp, 246 unsigned int cmd, void __user *argp) 247 { 248 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 249 struct nilfs_cpstat cpstat; 250 int ret; 251 252 down_read(&nilfs->ns_segctor_sem); 253 ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat); 254 up_read(&nilfs->ns_segctor_sem); 255 if (ret < 0) 256 return ret; 257 258 if (copy_to_user(argp, &cpstat, sizeof(cpstat))) 259 ret = -EFAULT; 260 return ret; 261 } 262 263 static ssize_t 264 nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, 265 void *buf, size_t size, size_t nmembs) 266 { 267 int ret; 268 269 down_read(&nilfs->ns_segctor_sem); 270 ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size, 271 nmembs); 272 up_read(&nilfs->ns_segctor_sem); 273 return ret; 274 } 275 276 static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp, 277 unsigned int cmd, void __user *argp) 278 { 279 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 280 struct nilfs_sustat sustat; 281 int ret; 282 283 down_read(&nilfs->ns_segctor_sem); 284 ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat); 285 up_read(&nilfs->ns_segctor_sem); 286 if (ret < 0) 287 return ret; 288 289 if (copy_to_user(argp, &sustat, sizeof(sustat))) 290 ret = -EFAULT; 291 return ret; 292 } 293 294 static ssize_t 295 nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags, 296 void *buf, size_t size, size_t nmembs) 297 { 298 int ret; 299 300 down_read(&nilfs->ns_segctor_sem); 301 ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs); 302 up_read(&nilfs->ns_segctor_sem); 303 return ret; 304 } 305 306 static ssize_t 307 nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags, 308 void *buf, size_t size, size_t nmembs) 309 { 310 struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap; 311 struct nilfs_bdesc *bdescs = buf; 312 int ret, i; 313 314 down_read(&nilfs->ns_segctor_sem); 315 for (i = 0; i < nmembs; i++) { 316 ret = nilfs_bmap_lookup_at_level(bmap, 317 bdescs[i].bd_offset, 318 bdescs[i].bd_level + 1, 319 &bdescs[i].bd_blocknr); 320 if (ret < 0) { 321 if (ret != -ENOENT) { 322 up_read(&nilfs->ns_segctor_sem); 323 return ret; 324 } 325 bdescs[i].bd_blocknr = 0; 326 } 327 } 328 up_read(&nilfs->ns_segctor_sem); 329 return nmembs; 330 } 331 332 static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp, 333 unsigned int cmd, void __user *argp) 334 { 335 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 336 struct nilfs_argv argv; 337 int ret; 338 339 if (copy_from_user(&argv, argp, sizeof(argv))) 340 return -EFAULT; 341 342 if (argv.v_size != sizeof(struct nilfs_bdesc)) 343 return -EINVAL; 344 345 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 346 nilfs_ioctl_do_get_bdescs); 347 if (ret < 0) 348 return ret; 349 350 if (copy_to_user(argp, &argv, sizeof(argv))) 351 ret = -EFAULT; 352 return ret; 353 } 354 355 static int nilfs_ioctl_move_inode_block(struct inode *inode, 356 struct nilfs_vdesc *vdesc, 357 struct list_head *buffers) 358 { 359 struct buffer_head *bh; 360 int ret; 361 362 if (vdesc->vd_flags == 0) 363 ret = nilfs_gccache_submit_read_data( 364 inode, vdesc->vd_offset, vdesc->vd_blocknr, 365 vdesc->vd_vblocknr, &bh); 366 else 367 ret = nilfs_gccache_submit_read_node( 368 inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh); 369 370 if (unlikely(ret < 0)) { 371 if (ret == -ENOENT) 372 printk(KERN_CRIT 373 "%s: invalid virtual block address (%s): " 374 "ino=%llu, cno=%llu, offset=%llu, " 375 "blocknr=%llu, vblocknr=%llu\n", 376 __func__, vdesc->vd_flags ? "node" : "data", 377 (unsigned long long)vdesc->vd_ino, 378 (unsigned long long)vdesc->vd_cno, 379 (unsigned long long)vdesc->vd_offset, 380 (unsigned long long)vdesc->vd_blocknr, 381 (unsigned long long)vdesc->vd_vblocknr); 382 return ret; 383 } 384 if (unlikely(!list_empty(&bh->b_assoc_buffers))) { 385 printk(KERN_CRIT "%s: conflicting %s buffer: ino=%llu, " 386 "cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu\n", 387 __func__, vdesc->vd_flags ? "node" : "data", 388 (unsigned long long)vdesc->vd_ino, 389 (unsigned long long)vdesc->vd_cno, 390 (unsigned long long)vdesc->vd_offset, 391 (unsigned long long)vdesc->vd_blocknr, 392 (unsigned long long)vdesc->vd_vblocknr); 393 brelse(bh); 394 return -EEXIST; 395 } 396 list_add_tail(&bh->b_assoc_buffers, buffers); 397 return 0; 398 } 399 400 static int nilfs_ioctl_move_blocks(struct super_block *sb, 401 struct nilfs_argv *argv, void *buf) 402 { 403 size_t nmembs = argv->v_nmembs; 404 struct the_nilfs *nilfs = sb->s_fs_info; 405 struct inode *inode; 406 struct nilfs_vdesc *vdesc; 407 struct buffer_head *bh, *n; 408 LIST_HEAD(buffers); 409 ino_t ino; 410 __u64 cno; 411 int i, ret; 412 413 for (i = 0, vdesc = buf; i < nmembs; ) { 414 ino = vdesc->vd_ino; 415 cno = vdesc->vd_cno; 416 inode = nilfs_iget_for_gc(sb, ino, cno); 417 if (IS_ERR(inode)) { 418 ret = PTR_ERR(inode); 419 goto failed; 420 } 421 if (list_empty(&NILFS_I(inode)->i_dirty)) { 422 /* 423 * Add the inode to GC inode list. Garbage Collection 424 * is serialized and no two processes manipulate the 425 * list simultaneously. 426 */ 427 igrab(inode); 428 list_add(&NILFS_I(inode)->i_dirty, 429 &nilfs->ns_gc_inodes); 430 } 431 432 do { 433 ret = nilfs_ioctl_move_inode_block(inode, vdesc, 434 &buffers); 435 if (unlikely(ret < 0)) { 436 iput(inode); 437 goto failed; 438 } 439 vdesc++; 440 } while (++i < nmembs && 441 vdesc->vd_ino == ino && vdesc->vd_cno == cno); 442 443 iput(inode); /* The inode still remains in GC inode list */ 444 } 445 446 list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) { 447 ret = nilfs_gccache_wait_and_mark_dirty(bh); 448 if (unlikely(ret < 0)) { 449 WARN_ON(ret == -EEXIST); 450 goto failed; 451 } 452 list_del_init(&bh->b_assoc_buffers); 453 brelse(bh); 454 } 455 return nmembs; 456 457 failed: 458 list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) { 459 list_del_init(&bh->b_assoc_buffers); 460 brelse(bh); 461 } 462 return ret; 463 } 464 465 static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs, 466 struct nilfs_argv *argv, void *buf) 467 { 468 size_t nmembs = argv->v_nmembs; 469 struct inode *cpfile = nilfs->ns_cpfile; 470 struct nilfs_period *periods = buf; 471 int ret, i; 472 473 for (i = 0; i < nmembs; i++) { 474 ret = nilfs_cpfile_delete_checkpoints( 475 cpfile, periods[i].p_start, periods[i].p_end); 476 if (ret < 0) 477 return ret; 478 } 479 return nmembs; 480 } 481 482 static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs, 483 struct nilfs_argv *argv, void *buf) 484 { 485 size_t nmembs = argv->v_nmembs; 486 int ret; 487 488 ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs); 489 490 return (ret < 0) ? ret : nmembs; 491 } 492 493 static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs, 494 struct nilfs_argv *argv, void *buf) 495 { 496 size_t nmembs = argv->v_nmembs; 497 struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap; 498 struct nilfs_bdesc *bdescs = buf; 499 int ret, i; 500 501 for (i = 0; i < nmembs; i++) { 502 /* XXX: use macro or inline func to check liveness */ 503 ret = nilfs_bmap_lookup_at_level(bmap, 504 bdescs[i].bd_offset, 505 bdescs[i].bd_level + 1, 506 &bdescs[i].bd_blocknr); 507 if (ret < 0) { 508 if (ret != -ENOENT) 509 return ret; 510 bdescs[i].bd_blocknr = 0; 511 } 512 if (bdescs[i].bd_blocknr != bdescs[i].bd_oblocknr) 513 /* skip dead block */ 514 continue; 515 if (bdescs[i].bd_level == 0) { 516 ret = nilfs_mdt_mark_block_dirty(nilfs->ns_dat, 517 bdescs[i].bd_offset); 518 if (ret < 0) { 519 WARN_ON(ret == -ENOENT); 520 return ret; 521 } 522 } else { 523 ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset, 524 bdescs[i].bd_level); 525 if (ret < 0) { 526 WARN_ON(ret == -ENOENT); 527 return ret; 528 } 529 } 530 } 531 return nmembs; 532 } 533 534 int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, 535 struct nilfs_argv *argv, void **kbufs) 536 { 537 const char *msg; 538 int ret; 539 540 ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]); 541 if (ret < 0) { 542 /* 543 * can safely abort because checkpoints can be removed 544 * independently. 545 */ 546 msg = "cannot delete checkpoints"; 547 goto failed; 548 } 549 ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]); 550 if (ret < 0) { 551 /* 552 * can safely abort because DAT file is updated atomically 553 * using a copy-on-write technique. 554 */ 555 msg = "cannot delete virtual blocks from DAT file"; 556 goto failed; 557 } 558 ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]); 559 if (ret < 0) { 560 /* 561 * can safely abort because the operation is nondestructive. 562 */ 563 msg = "cannot mark copying blocks dirty"; 564 goto failed; 565 } 566 return 0; 567 568 failed: 569 printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n", 570 msg, ret); 571 return ret; 572 } 573 574 static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, 575 unsigned int cmd, void __user *argp) 576 { 577 struct nilfs_argv argv[5]; 578 static const size_t argsz[5] = { 579 sizeof(struct nilfs_vdesc), 580 sizeof(struct nilfs_period), 581 sizeof(__u64), 582 sizeof(struct nilfs_bdesc), 583 sizeof(__u64), 584 }; 585 void __user *base; 586 void *kbufs[5]; 587 struct the_nilfs *nilfs; 588 size_t len, nsegs; 589 int n, ret; 590 591 if (!capable(CAP_SYS_ADMIN)) 592 return -EPERM; 593 594 ret = mnt_want_write_file(filp); 595 if (ret) 596 return ret; 597 598 ret = -EFAULT; 599 if (copy_from_user(argv, argp, sizeof(argv))) 600 goto out; 601 602 ret = -EINVAL; 603 nsegs = argv[4].v_nmembs; 604 if (argv[4].v_size != argsz[4]) 605 goto out; 606 if (nsegs > UINT_MAX / sizeof(__u64)) 607 goto out; 608 609 /* 610 * argv[4] points to segment numbers this ioctl cleans. We 611 * use kmalloc() for its buffer because memory used for the 612 * segment numbers is enough small. 613 */ 614 kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base, 615 nsegs * sizeof(__u64)); 616 if (IS_ERR(kbufs[4])) { 617 ret = PTR_ERR(kbufs[4]); 618 goto out; 619 } 620 nilfs = inode->i_sb->s_fs_info; 621 622 for (n = 0; n < 4; n++) { 623 ret = -EINVAL; 624 if (argv[n].v_size != argsz[n]) 625 goto out_free; 626 627 if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment) 628 goto out_free; 629 630 if (argv[n].v_nmembs >= UINT_MAX / argv[n].v_size) 631 goto out_free; 632 633 len = argv[n].v_size * argv[n].v_nmembs; 634 base = (void __user *)(unsigned long)argv[n].v_base; 635 if (len == 0) { 636 kbufs[n] = NULL; 637 continue; 638 } 639 640 kbufs[n] = vmalloc(len); 641 if (!kbufs[n]) { 642 ret = -ENOMEM; 643 goto out_free; 644 } 645 if (copy_from_user(kbufs[n], base, len)) { 646 ret = -EFAULT; 647 vfree(kbufs[n]); 648 goto out_free; 649 } 650 } 651 652 /* 653 * nilfs_ioctl_move_blocks() will call nilfs_iget_for_gc(), 654 * which will operates an inode list without blocking. 655 * To protect the list from concurrent operations, 656 * nilfs_ioctl_move_blocks should be atomic operation. 657 */ 658 if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) { 659 ret = -EBUSY; 660 goto out_free; 661 } 662 663 ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]); 664 if (ret < 0) 665 printk(KERN_ERR "NILFS: GC failed during preparation: " 666 "cannot read source blocks: err=%d\n", ret); 667 else { 668 if (nilfs_sb_need_update(nilfs)) 669 set_nilfs_discontinued(nilfs); 670 ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); 671 } 672 673 nilfs_remove_all_gcinodes(nilfs); 674 clear_nilfs_gc_running(nilfs); 675 676 out_free: 677 while (--n >= 0) 678 vfree(kbufs[n]); 679 kfree(kbufs[4]); 680 out: 681 mnt_drop_write_file(filp); 682 return ret; 683 } 684 685 static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, 686 unsigned int cmd, void __user *argp) 687 { 688 __u64 cno; 689 int ret; 690 struct the_nilfs *nilfs; 691 692 ret = nilfs_construct_segment(inode->i_sb); 693 if (ret < 0) 694 return ret; 695 696 nilfs = inode->i_sb->s_fs_info; 697 if (nilfs_test_opt(nilfs, BARRIER)) { 698 ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); 699 if (ret == -EIO) 700 return ret; 701 } 702 703 if (argp != NULL) { 704 down_read(&nilfs->ns_segctor_sem); 705 cno = nilfs->ns_cno - 1; 706 up_read(&nilfs->ns_segctor_sem); 707 if (copy_to_user(argp, &cno, sizeof(cno))) 708 return -EFAULT; 709 } 710 return 0; 711 } 712 713 static int nilfs_ioctl_resize(struct inode *inode, struct file *filp, 714 void __user *argp) 715 { 716 __u64 newsize; 717 int ret = -EPERM; 718 719 if (!capable(CAP_SYS_ADMIN)) 720 goto out; 721 722 ret = mnt_want_write_file(filp); 723 if (ret) 724 goto out; 725 726 ret = -EFAULT; 727 if (copy_from_user(&newsize, argp, sizeof(newsize))) 728 goto out_drop_write; 729 730 ret = nilfs_resize_fs(inode->i_sb, newsize); 731 732 out_drop_write: 733 mnt_drop_write_file(filp); 734 out: 735 return ret; 736 } 737 738 static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp) 739 { 740 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 741 __u64 range[2]; 742 __u64 minseg, maxseg; 743 unsigned long segbytes; 744 int ret = -EPERM; 745 746 if (!capable(CAP_SYS_ADMIN)) 747 goto out; 748 749 ret = -EFAULT; 750 if (copy_from_user(range, argp, sizeof(__u64[2]))) 751 goto out; 752 753 ret = -ERANGE; 754 if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode)) 755 goto out; 756 757 segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize; 758 759 minseg = range[0] + segbytes - 1; 760 do_div(minseg, segbytes); 761 maxseg = NILFS_SB2_OFFSET_BYTES(range[1]); 762 do_div(maxseg, segbytes); 763 maxseg--; 764 765 ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg); 766 out: 767 return ret; 768 } 769 770 static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, 771 unsigned int cmd, void __user *argp, 772 size_t membsz, 773 ssize_t (*dofunc)(struct the_nilfs *, 774 __u64 *, int, 775 void *, size_t, size_t)) 776 777 { 778 struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 779 struct nilfs_argv argv; 780 int ret; 781 782 if (copy_from_user(&argv, argp, sizeof(argv))) 783 return -EFAULT; 784 785 if (argv.v_size < membsz) 786 return -EINVAL; 787 788 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc); 789 if (ret < 0) 790 return ret; 791 792 if (copy_to_user(argp, &argv, sizeof(argv))) 793 ret = -EFAULT; 794 return ret; 795 } 796 797 long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 798 { 799 struct inode *inode = file_inode(filp); 800 void __user *argp = (void __user *)arg; 801 802 switch (cmd) { 803 case FS_IOC_GETFLAGS: 804 return nilfs_ioctl_getflags(inode, argp); 805 case FS_IOC_SETFLAGS: 806 return nilfs_ioctl_setflags(inode, filp, argp); 807 case FS_IOC_GETVERSION: 808 return nilfs_ioctl_getversion(inode, argp); 809 case NILFS_IOCTL_CHANGE_CPMODE: 810 return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp); 811 case NILFS_IOCTL_DELETE_CHECKPOINT: 812 return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp); 813 case NILFS_IOCTL_GET_CPINFO: 814 return nilfs_ioctl_get_info(inode, filp, cmd, argp, 815 sizeof(struct nilfs_cpinfo), 816 nilfs_ioctl_do_get_cpinfo); 817 case NILFS_IOCTL_GET_CPSTAT: 818 return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp); 819 case NILFS_IOCTL_GET_SUINFO: 820 return nilfs_ioctl_get_info(inode, filp, cmd, argp, 821 sizeof(struct nilfs_suinfo), 822 nilfs_ioctl_do_get_suinfo); 823 case NILFS_IOCTL_GET_SUSTAT: 824 return nilfs_ioctl_get_sustat(inode, filp, cmd, argp); 825 case NILFS_IOCTL_GET_VINFO: 826 return nilfs_ioctl_get_info(inode, filp, cmd, argp, 827 sizeof(struct nilfs_vinfo), 828 nilfs_ioctl_do_get_vinfo); 829 case NILFS_IOCTL_GET_BDESCS: 830 return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp); 831 case NILFS_IOCTL_CLEAN_SEGMENTS: 832 return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); 833 case NILFS_IOCTL_SYNC: 834 return nilfs_ioctl_sync(inode, filp, cmd, argp); 835 case NILFS_IOCTL_RESIZE: 836 return nilfs_ioctl_resize(inode, filp, argp); 837 case NILFS_IOCTL_SET_ALLOC_RANGE: 838 return nilfs_ioctl_set_alloc_range(inode, argp); 839 default: 840 return -ENOTTY; 841 } 842 } 843 844 #ifdef CONFIG_COMPAT 845 long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 846 { 847 switch (cmd) { 848 case FS_IOC32_GETFLAGS: 849 cmd = FS_IOC_GETFLAGS; 850 break; 851 case FS_IOC32_SETFLAGS: 852 cmd = FS_IOC_SETFLAGS; 853 break; 854 case FS_IOC32_GETVERSION: 855 cmd = FS_IOC_GETVERSION; 856 break; 857 case NILFS_IOCTL_CHANGE_CPMODE: 858 case NILFS_IOCTL_DELETE_CHECKPOINT: 859 case NILFS_IOCTL_GET_CPINFO: 860 case NILFS_IOCTL_GET_CPSTAT: 861 case NILFS_IOCTL_GET_SUINFO: 862 case NILFS_IOCTL_GET_SUSTAT: 863 case NILFS_IOCTL_GET_VINFO: 864 case NILFS_IOCTL_GET_BDESCS: 865 case NILFS_IOCTL_CLEAN_SEGMENTS: 866 case NILFS_IOCTL_SYNC: 867 case NILFS_IOCTL_RESIZE: 868 case NILFS_IOCTL_SET_ALLOC_RANGE: 869 break; 870 default: 871 return -ENOIOCTLCMD; 872 } 873 return nilfs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); 874 } 875 #endif 876