aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/ioctl.c')
-rw-r--r--fs/nilfs2/ioctl.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index cfb27892ffe8..108d281ebca5 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -489,14 +489,14 @@ nilfs_ioctl_do_mark_blocks_dirty(struct the_nilfs *nilfs, __u64 *posp,
489 ret = nilfs_mdt_mark_block_dirty(dat, 489 ret = nilfs_mdt_mark_block_dirty(dat,
490 bdescs[i].bd_offset); 490 bdescs[i].bd_offset);
491 if (ret < 0) { 491 if (ret < 0) {
492 BUG_ON(ret == -ENOENT); 492 WARN_ON(ret == -ENOENT);
493 return ret; 493 return ret;
494 } 494 }
495 } else { 495 } else {
496 ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset, 496 ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset,
497 bdescs[i].bd_level); 497 bdescs[i].bd_level);
498 if (ret < 0) { 498 if (ret < 0) {
499 BUG_ON(ret == -ENOENT); 499 WARN_ON(ret == -ENOENT);
500 return ret; 500 return ret;
501 } 501 }
502 } 502 }
@@ -519,7 +519,8 @@ nilfs_ioctl_do_free_segments(struct the_nilfs *nilfs, __u64 *posp, int flags,
519 struct nilfs_sb_info *sbi = nilfs_get_writer(nilfs); 519 struct nilfs_sb_info *sbi = nilfs_get_writer(nilfs);
520 int ret; 520 int ret;
521 521
522 BUG_ON(!sbi); 522 if (unlikely(!sbi))
523 return -EROFS;
523 ret = nilfs_segctor_add_segments_to_be_freed( 524 ret = nilfs_segctor_add_segments_to_be_freed(
524 NILFS_SC(sbi), buf, nmembs); 525 NILFS_SC(sbi), buf, nmembs);
525 nilfs_put_writer(nilfs); 526 nilfs_put_writer(nilfs);
@@ -539,6 +540,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
539 void __user *argp) 540 void __user *argp)
540{ 541{
541 struct nilfs_argv argv[5]; 542 struct nilfs_argv argv[5];
543 const char *msg;
542 int dir, ret; 544 int dir, ret;
543 545
544 if (copy_from_user(argv, argp, sizeof(argv))) 546 if (copy_from_user(argv, argp, sizeof(argv)))
@@ -546,31 +548,50 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
546 548
547 dir = _IOC_WRITE; 549 dir = _IOC_WRITE;
548 ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], dir); 550 ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], dir);
549 if (ret < 0) 551 if (ret < 0) {
550 goto out_move_blks; 552 msg = "cannot read source blocks";
553 goto failed;
554 }
551 ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], dir); 555 ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], dir);
552 if (ret < 0) 556 if (ret < 0) {
553 goto out_del_cps; 557 /*
558 * can safely abort because checkpoints can be removed
559 * independently.
560 */
561 msg = "cannot delete checkpoints";
562 goto failed;
563 }
554 ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], dir); 564 ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], dir);
555 if (ret < 0) 565 if (ret < 0) {
556 goto out_free_vbns; 566 /*
567 * can safely abort because DAT file is updated atomically
568 * using a copy-on-write technique.
569 */
570 msg = "cannot delete virtual blocks from DAT file";
571 goto failed;
572 }
557 ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], dir); 573 ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], dir);
558 if (ret < 0) 574 if (ret < 0) {
559 goto out_free_vbns; 575 /*
576 * can safely abort because the operation is nondestructive.
577 */
578 msg = "cannot mark copying blocks dirty";
579 goto failed;
580 }
560 ret = nilfs_ioctl_free_segments(nilfs, &argv[4], dir); 581 ret = nilfs_ioctl_free_segments(nilfs, &argv[4], dir);
561 if (ret < 0) 582 if (ret < 0) {
562 goto out_free_segs; 583 /*
563 584 * can safely abort because this operation is atomic.
585 */
586 msg = "cannot set segments to be freed";
587 goto failed;
588 }
564 return 0; 589 return 0;
565 590
566 out_free_segs: 591 failed:
567 BUG(); /* XXX: not implemented yet */
568 out_free_vbns:
569 BUG();/* XXX: not implemented yet */
570 out_del_cps:
571 BUG();/* XXX: not implemented yet */
572 out_move_blks:
573 nilfs_remove_all_gcinode(nilfs); 592 nilfs_remove_all_gcinode(nilfs);
593 printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
594 msg, ret);
574 return ret; 595 return ret;
575} 596}
576 597