Commit 5beb6e0b2008386571fd342d0a4a14f5c8c0baf8

Authored by Ryusuke Konishi
1 parent c05dbfc260

nilfs2: add bdev freeze/thaw support

Nilfs hasn't supported the freeze/thaw feature because it didn't work
due to the peculiar design that multiple super block instances could
be allocated for a device.  This limitation was removed by the patch
"nilfs2: do not allocate multiple super block instances for a device".

So now this adds the freeze/thaw support to nilfs.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>

Showing 3 changed files with 58 additions and 4 deletions Side-by-side Diff

... ... @@ -580,6 +580,8 @@
580 580 goto out_free;
581 581 }
582 582  
  583 + vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
  584 +
583 585 ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
584 586 if (ret < 0)
585 587 printk(KERN_ERR "NILFS: GC failed during preparation: "
... ... @@ -191,6 +191,8 @@
191 191 if (ret > 0)
192 192 return 0;
193 193  
  194 + vfs_check_frozen(sb, SB_FREEZE_WRITE);
  195 +
194 196 sbi = NILFS_SB(sb);
195 197 nilfs = sbi->s_nilfs;
196 198 down_read(&nilfs->ns_segctor_sem);
... ... @@ -73,6 +73,7 @@
73 73 struct kmem_cache *nilfs_segbuf_cachep;
74 74 struct kmem_cache *nilfs_btree_path_cache;
75 75  
  76 +static int nilfs_setup_super(struct nilfs_sb_info *sbi, int is_mount);
76 77 static int nilfs_remount(struct super_block *sb, int *flags, char *data);
77 78  
78 79 static void nilfs_set_error(struct nilfs_sb_info *sbi)
... ... @@ -439,6 +440,36 @@
439 440 return err;
440 441 }
441 442  
  443 +static int nilfs_freeze(struct super_block *sb)
  444 +{
  445 + struct nilfs_sb_info *sbi = NILFS_SB(sb);
  446 + struct the_nilfs *nilfs = sbi->s_nilfs;
  447 + int err;
  448 +
  449 + if (sb->s_flags & MS_RDONLY)
  450 + return 0;
  451 +
  452 + /* Mark super block clean */
  453 + down_write(&nilfs->ns_sem);
  454 + err = nilfs_cleanup_super(sbi);
  455 + up_write(&nilfs->ns_sem);
  456 + return err;
  457 +}
  458 +
  459 +static int nilfs_unfreeze(struct super_block *sb)
  460 +{
  461 + struct nilfs_sb_info *sbi = NILFS_SB(sb);
  462 + struct the_nilfs *nilfs = sbi->s_nilfs;
  463 +
  464 + if (sb->s_flags & MS_RDONLY)
  465 + return 0;
  466 +
  467 + down_write(&nilfs->ns_sem);
  468 + nilfs_setup_super(sbi, false);
  469 + up_write(&nilfs->ns_sem);
  470 + return 0;
  471 +}
  472 +
442 473 static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
443 474 {
444 475 struct super_block *sb = dentry->d_sb;
... ... @@ -523,6 +554,8 @@
523 554 .put_super = nilfs_put_super,
524 555 /* .write_super = nilfs_write_super, */
525 556 .sync_fs = nilfs_sync_fs,
  557 + .freeze_fs = nilfs_freeze,
  558 + .unfreeze_fs = nilfs_unfreeze,
526 559 /* .write_super_lockfs */
527 560 /* .unlockfs */
528 561 .statfs = nilfs_statfs,
... ... @@ -626,7 +659,7 @@
626 659 NILFS_MOUNT_ERRORS_RO | NILFS_MOUNT_BARRIER;
627 660 }
628 661  
629   -static int nilfs_setup_super(struct nilfs_sb_info *sbi)
  662 +static int nilfs_setup_super(struct nilfs_sb_info *sbi, int is_mount)
630 663 {
631 664 struct the_nilfs *nilfs = sbi->s_nilfs;
632 665 struct nilfs_super_block **sbp;
... ... @@ -638,6 +671,9 @@
638 671 if (!sbp)
639 672 return -EIO;
640 673  
  674 + if (!is_mount)
  675 + goto skip_mount_setup;
  676 +
641 677 max_mnt_count = le16_to_cpu(sbp[0]->s_max_mnt_count);
642 678 mnt_count = le16_to_cpu(sbp[0]->s_mnt_count);
643 679  
644 680  
... ... @@ -654,9 +690,11 @@
654 690 sbp[0]->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT);
655 691  
656 692 sbp[0]->s_mnt_count = cpu_to_le16(mnt_count + 1);
  693 + sbp[0]->s_mtime = cpu_to_le64(get_seconds());
  694 +
  695 +skip_mount_setup:
657 696 sbp[0]->s_state =
658 697 cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS);
659   - sbp[0]->s_mtime = cpu_to_le64(get_seconds());
660 698 /* synchronize sbp[1] with sbp[0] */
661 699 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
662 700 return nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
... ... @@ -938,7 +976,7 @@
938 976  
939 977 if (!(sb->s_flags & MS_RDONLY)) {
940 978 down_write(&nilfs->ns_sem);
941   - nilfs_setup_super(sbi);
  979 + nilfs_setup_super(sbi, true);
942 980 up_write(&nilfs->ns_sem);
943 981 }
944 982  
... ... @@ -1034,7 +1072,7 @@
1034 1072 goto restore_opts;
1035 1073  
1036 1074 down_write(&nilfs->ns_sem);
1037   - nilfs_setup_super(sbi);
  1075 + nilfs_setup_super(sbi, true);
1038 1076 up_write(&nilfs->ns_sem);
1039 1077 }
1040 1078 out:
1041 1079  
... ... @@ -1132,7 +1170,19 @@
1132 1170 goto failed;
1133 1171 }
1134 1172  
  1173 + /*
  1174 + * once the super is inserted into the list by sget, s_umount
  1175 + * will protect the lockfs code from trying to start a snapshot
  1176 + * while we are mounting
  1177 + */
  1178 + mutex_lock(&sd.bdev->bd_fsfreeze_mutex);
  1179 + if (sd.bdev->bd_fsfreeze_count > 0) {
  1180 + mutex_unlock(&sd.bdev->bd_fsfreeze_mutex);
  1181 + err = -EBUSY;
  1182 + goto failed;
  1183 + }
1135 1184 s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, sd.bdev);
  1185 + mutex_unlock(&sd.bdev->bd_fsfreeze_mutex);
1136 1186 if (IS_ERR(s)) {
1137 1187 err = PTR_ERR(s);
1138 1188 goto failed;