summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorQu Wenruo2016-01-19 03:23:03 +0100
committerDavid Sterba2016-02-12 15:14:49 +0100
commit96da09192cda57a356467bd7c91a3641a2e78490 (patch)
tree7b9e18344074d9bf9c1d71fd6fb0670922937283 /fs/btrfs/super.c
parentbtrfs: Introduce new mount option usebackuproot to replace recovery (diff)
downloadkernel-qcow2-linux-96da09192cda57a356467bd7c91a3641a2e78490.tar.gz
kernel-qcow2-linux-96da09192cda57a356467bd7c91a3641a2e78490.tar.xz
kernel-qcow2-linux-96da09192cda57a356467bd7c91a3641a2e78490.zip
btrfs: Introduce new mount option to disable tree log replay
Introduce a new mount option "nologreplay" to co-operate with "ro" mount option to get real readonly mount, like "norecovery" in ext* and xfs. Since the new parse_options() need to check new flags at remount time, so add a new parameter for parse_options(). Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Reviewed-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Tested-by: Austin S. Hemmelgarn <ahferroin7@gmail.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 7ed3863c264b..e8a7a9f88195 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -304,6 +304,7 @@ enum {
Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard,
Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow,
Opt_datasum, Opt_treelog, Opt_noinode_cache, Opt_usebackuproot,
+ Opt_nologreplay,
#ifdef CONFIG_BTRFS_DEBUG
Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
#endif
@@ -335,6 +336,7 @@ static const match_table_t tokens = {
{Opt_noacl, "noacl"},
{Opt_notreelog, "notreelog"},
{Opt_treelog, "treelog"},
+ {Opt_nologreplay, "nologreplay"},
{Opt_flushoncommit, "flushoncommit"},
{Opt_noflushoncommit, "noflushoncommit"},
{Opt_ratio, "metadata_ratio=%d"},
@@ -374,7 +376,8 @@ static const match_table_t tokens = {
* reading in a new superblock is parsed here.
* XXX JDM: This needs to be cleaned up for remount.
*/
-int btrfs_parse_options(struct btrfs_root *root, char *options)
+int btrfs_parse_options(struct btrfs_root *root, char *options,
+ unsigned long new_flags)
{
struct btrfs_fs_info *info = root->fs_info;
substring_t args[MAX_OPT_ARGS];
@@ -394,8 +397,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
else if (cache_gen)
btrfs_set_opt(info->mount_opt, SPACE_CACHE);
+ /*
+ * Even the options are empty, we still need to do extra check
+ * against new flags
+ */
if (!options)
- goto out;
+ goto check;
/*
* strsep changes the string, duplicate it because parse_options
@@ -607,6 +614,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
btrfs_clear_and_info(root, NOTREELOG,
"enabling tree log");
break;
+ case Opt_nologreplay:
+ btrfs_set_and_info(root, NOLOGREPLAY,
+ "disabling log replay at mount time");
+ break;
case Opt_flushoncommit:
btrfs_set_and_info(root, FLUSHONCOMMIT,
"turning on flush-on-commit");
@@ -797,6 +808,15 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
break;
}
}
+check:
+ /*
+ * Extra check for current option against current flag
+ */
+ if (btrfs_test_opt(root, NOLOGREPLAY) && !(new_flags & MS_RDONLY)) {
+ btrfs_err(root->fs_info,
+ "nologreplay must be used with ro mount option");
+ ret = -EINVAL;
+ }
out:
if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) &&
!btrfs_test_opt(root, FREE_SPACE_TREE) &&
@@ -1207,6 +1227,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
seq_puts(seq, ",ssd");
if (btrfs_test_opt(root, NOTREELOG))
seq_puts(seq, ",notreelog");
+ if (btrfs_test_opt(root, NOLOGREPLAY))
+ seq_puts(seq, ",nologreplay");
if (btrfs_test_opt(root, FLUSHONCOMMIT))
seq_puts(seq, ",flushoncommit");
if (btrfs_test_opt(root, DISCARD))
@@ -1688,7 +1710,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
}
}
- ret = btrfs_parse_options(root, data);
+ ret = btrfs_parse_options(root, data, *flags);
if (ret) {
ret = -EINVAL;
goto restore;