aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/filesystems/nilfs2.txt4
-rw-r--r--fs/nilfs2/super.c16
-rw-r--r--fs/nilfs2/the_nilfs.c20
-rw-r--r--include/linux/nilfs2_fs.h2
4 files changed, 39 insertions, 3 deletions
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt
index cbd877978c80..4949fcaa6b6a 100644
--- a/Documentation/filesystems/nilfs2.txt
+++ b/Documentation/filesystems/nilfs2.txt
@@ -70,6 +70,10 @@ order=strict Apply strict in-order semantics that preserves sequence
70 blocks. That means, it is guaranteed that no 70 blocks. That means, it is guaranteed that no
71 overtaking of events occurs in the recovered file 71 overtaking of events occurs in the recovered file
72 system after a crash. 72 system after a crash.
73norecovery Disable recovery of the filesystem on mount.
74 This disables every write access on the device for
75 read-only mounts or snapshots. This option will fail
76 for r/w mounts on an unclean volume.
73 77
74NILFS2 usage 78NILFS2 usage
75============ 79============
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);
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
index 72289d2bb341..3fe02cf8b65a 100644
--- a/include/linux/nilfs2_fs.h
+++ b/include/linux/nilfs2_fs.h
@@ -151,6 +151,8 @@ struct nilfs_super_root {
151#define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */ 151#define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */
152#define NILFS_MOUNT_STRICT_ORDER 0x2000 /* Apply strict in-order 152#define NILFS_MOUNT_STRICT_ORDER 0x2000 /* Apply strict in-order
153 semantics also for data */ 153 semantics also for data */
154#define NILFS_MOUNT_NORECOVERY 0x4000 /* Disable write access during
155 mount-time recovery */
154 156
155 157
156/** 158/**