aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-11-19 13:28:01 -0500
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-11-19 20:05:52 -0500
commit0234576d041b9b2cc7043691ea61d2c2ca597aaa (patch)
tree1fd5f397cf0a7cb010a3e383a715438e64582b65 /fs/nilfs2
parenta057d2c01161444c48b12a60351ae6c7135f6e61 (diff)
nilfs2: add norecovery mount option
This adds "norecovery" mount option which disables temporal write access to read-only mounts or snapshots during mount/recovery. Without this option, write access will be even performed for those types of mounts; the temporal write access is needed to mount root file system read-only after an unclean shutdown. This option will be helpful when user wants to prevent any write access to the device. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Cc: Eric Sandeen <sandeen@redhat.com>
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/super.c16
-rw-r--r--fs/nilfs2/the_nilfs.c20
2 files changed, 33 insertions, 3 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 990ead43a833..5403b3ef3a42 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -479,6 +479,8 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
479 seq_printf(seq, ",errors=panic"); 479 seq_printf(seq, ",errors=panic");
480 if (nilfs_test_opt(sbi, STRICT_ORDER)) 480 if (nilfs_test_opt(sbi, STRICT_ORDER))
481 seq_printf(seq, ",order=strict"); 481 seq_printf(seq, ",order=strict");
482 if (nilfs_test_opt(sbi, NORECOVERY))
483 seq_printf(seq, ",norecovery");
482 484
483 return 0; 485 return 0;
484} 486}
@@ -547,7 +549,7 @@ static const struct export_operations nilfs_export_ops = {
547 549
548enum { 550enum {
549 Opt_err_cont, Opt_err_panic, Opt_err_ro, 551 Opt_err_cont, Opt_err_panic, Opt_err_ro,
550 Opt_nobarrier, Opt_snapshot, Opt_order, 552 Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
551 Opt_err, 553 Opt_err,
552}; 554};
553 555
@@ -558,6 +560,7 @@ static match_table_t tokens = {
558 {Opt_nobarrier, "nobarrier"}, 560 {Opt_nobarrier, "nobarrier"},
559 {Opt_snapshot, "cp=%u"}, 561 {Opt_snapshot, "cp=%u"},
560 {Opt_order, "order=%s"}, 562 {Opt_order, "order=%s"},
563 {Opt_norecovery, "norecovery"},
561 {Opt_err, NULL} 564 {Opt_err, NULL}
562}; 565};
563 566
@@ -608,6 +611,9 @@ static int parse_options(char *options, struct super_block *sb)
608 sbi->s_snapshot_cno = option; 611 sbi->s_snapshot_cno = option;
609 nilfs_set_opt(sbi, SNAPSHOT); 612 nilfs_set_opt(sbi, SNAPSHOT);
610 break; 613 break;
614 case Opt_norecovery:
615 nilfs_set_opt(sbi, NORECOVERY);
616 break;
611 default: 617 default:
612 printk(KERN_ERR 618 printk(KERN_ERR
613 "NILFS: Unrecognized mount option \"%s\"\n", p); 619 "NILFS: Unrecognized mount option \"%s\"\n", p);
@@ -863,6 +869,14 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
863 goto restore_opts; 869 goto restore_opts;
864 } 870 }
865 871
872 if (!nilfs_valid_fs(nilfs)) {
873 printk(KERN_WARNING "NILFS (device %s): couldn't "
874 "remount because the filesystem is in an "
875 "incomplete recovery state.\n", sb->s_id);
876 err = -EINVAL;
877 goto restore_opts;
878 }
879
866 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 880 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
867 goto out; 881 goto out;
868 if (*flags & MS_RDONLY) { 882 if (*flags & MS_RDONLY) {
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 890a8d3886cf..6241e1722efc 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -264,8 +264,14 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
264 int valid_fs = nilfs_valid_fs(nilfs); 264 int valid_fs = nilfs_valid_fs(nilfs);
265 int err; 265 int err;
266 266
267 if (nilfs_loaded(nilfs)) 267 if (nilfs_loaded(nilfs)) {
268 return 0; 268 if (valid_fs ||
269 ((s_flags & MS_RDONLY) && nilfs_test_opt(sbi, NORECOVERY)))
270 return 0;
271 printk(KERN_ERR "NILFS: the filesystem is in an incomplete "
272 "recovery state.\n");
273 return -EINVAL;
274 }
269 275
270 if (!valid_fs) { 276 if (!valid_fs) {
271 printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n"); 277 printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
@@ -295,6 +301,11 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
295 goto skip_recovery; 301 goto skip_recovery;
296 302
297 if (s_flags & MS_RDONLY) { 303 if (s_flags & MS_RDONLY) {
304 if (nilfs_test_opt(sbi, NORECOVERY)) {
305 printk(KERN_INFO "NILFS: norecovery option specified. "
306 "skipping roll-forward recovery\n");
307 goto skip_recovery;
308 }
298 if (really_read_only) { 309 if (really_read_only) {
299 printk(KERN_ERR "NILFS: write access " 310 printk(KERN_ERR "NILFS: write access "
300 "unavailable, cannot proceed.\n"); 311 "unavailable, cannot proceed.\n");
@@ -302,6 +313,11 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
302 goto failed_unload; 313 goto failed_unload;
303 } 314 }
304 sbi->s_super->s_flags &= ~MS_RDONLY; 315 sbi->s_super->s_flags &= ~MS_RDONLY;
316 } else if (nilfs_test_opt(sbi, NORECOVERY)) {
317 printk(KERN_ERR "NILFS: recovery cancelled because norecovery "
318 "option was specified for a read/write mount\n");
319 err = -EINVAL;
320 goto failed_unload;
305 } 321 }
306 322
307 err = nilfs_recover_logical_segments(nilfs, sbi, &ri); 323 err = nilfs_recover_logical_segments(nilfs, sbi, &ri);