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>
This commit is contained in:
parent
8dcddfa048
commit
96da09192c
@ -168,6 +168,14 @@ Options with (*) are default options and will not show in the mount options.
|
|||||||
notreelog
|
notreelog
|
||||||
Enable/disable the tree logging used for fsync and O_SYNC writes.
|
Enable/disable the tree logging used for fsync and O_SYNC writes.
|
||||||
|
|
||||||
|
nologreplay
|
||||||
|
Disable the log tree replay at mount time to prevent filesystem
|
||||||
|
from getting modified.
|
||||||
|
Must be used with 'ro' mount option.
|
||||||
|
A filesystem mounted with this option cannot transition to a
|
||||||
|
read-write mount via remount,rw - the filesystem must be unmounted
|
||||||
|
and mounted back again if read-write access is desired.
|
||||||
|
|
||||||
usebackuproot
|
usebackuproot
|
||||||
Enable attempts to use backup tree roots if a bad tree root is found at
|
Enable attempts to use backup tree roots if a bad tree root is found at
|
||||||
mount time.
|
mount time.
|
||||||
|
@ -2250,6 +2250,7 @@ struct btrfs_ioctl_defrag_range_args {
|
|||||||
#define BTRFS_MOUNT_FRAGMENT_DATA (1 << 24)
|
#define BTRFS_MOUNT_FRAGMENT_DATA (1 << 24)
|
||||||
#define BTRFS_MOUNT_FRAGMENT_METADATA (1 << 25)
|
#define BTRFS_MOUNT_FRAGMENT_METADATA (1 << 25)
|
||||||
#define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 26)
|
#define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 26)
|
||||||
|
#define BTRFS_MOUNT_NOLOGREPLAY (1 << 27)
|
||||||
|
|
||||||
#define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
|
#define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
|
||||||
#define BTRFS_DEFAULT_MAX_INLINE (8192)
|
#define BTRFS_DEFAULT_MAX_INLINE (8192)
|
||||||
@ -4151,7 +4152,8 @@ void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
|
|||||||
ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
||||||
|
|
||||||
/* super.c */
|
/* super.c */
|
||||||
int btrfs_parse_options(struct btrfs_root *root, char *options);
|
int btrfs_parse_options(struct btrfs_root *root, char *options,
|
||||||
|
unsigned long new_flags);
|
||||||
int btrfs_sync_fs(struct super_block *sb, int wait);
|
int btrfs_sync_fs(struct super_block *sb, int wait);
|
||||||
|
|
||||||
#ifdef CONFIG_PRINTK
|
#ifdef CONFIG_PRINTK
|
||||||
|
@ -2750,7 +2750,7 @@ int open_ctree(struct super_block *sb,
|
|||||||
*/
|
*/
|
||||||
fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
|
fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
|
||||||
|
|
||||||
ret = btrfs_parse_options(tree_root, options);
|
ret = btrfs_parse_options(tree_root, options, sb->s_flags);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
err = ret;
|
err = ret;
|
||||||
goto fail_alloc;
|
goto fail_alloc;
|
||||||
@ -3029,8 +3029,9 @@ retry_root_backup:
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto fail_trans_kthread;
|
goto fail_trans_kthread;
|
||||||
|
|
||||||
/* do not make disk changes in broken FS */
|
/* do not make disk changes in broken FS or nologreplay is given */
|
||||||
if (btrfs_super_log_root(disk_super) != 0) {
|
if (btrfs_super_log_root(disk_super) != 0 &&
|
||||||
|
!btrfs_test_opt(tree_root, NOLOGREPLAY)) {
|
||||||
ret = btrfs_replay_log(fs_info, fs_devices);
|
ret = btrfs_replay_log(fs_info, fs_devices);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
err = ret;
|
err = ret;
|
||||||
|
@ -304,6 +304,7 @@ enum {
|
|||||||
Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard,
|
Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard,
|
||||||
Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow,
|
Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow,
|
||||||
Opt_datasum, Opt_treelog, Opt_noinode_cache, Opt_usebackuproot,
|
Opt_datasum, Opt_treelog, Opt_noinode_cache, Opt_usebackuproot,
|
||||||
|
Opt_nologreplay,
|
||||||
#ifdef CONFIG_BTRFS_DEBUG
|
#ifdef CONFIG_BTRFS_DEBUG
|
||||||
Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
|
Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
|
||||||
#endif
|
#endif
|
||||||
@ -335,6 +336,7 @@ static const match_table_t tokens = {
|
|||||||
{Opt_noacl, "noacl"},
|
{Opt_noacl, "noacl"},
|
||||||
{Opt_notreelog, "notreelog"},
|
{Opt_notreelog, "notreelog"},
|
||||||
{Opt_treelog, "treelog"},
|
{Opt_treelog, "treelog"},
|
||||||
|
{Opt_nologreplay, "nologreplay"},
|
||||||
{Opt_flushoncommit, "flushoncommit"},
|
{Opt_flushoncommit, "flushoncommit"},
|
||||||
{Opt_noflushoncommit, "noflushoncommit"},
|
{Opt_noflushoncommit, "noflushoncommit"},
|
||||||
{Opt_ratio, "metadata_ratio=%d"},
|
{Opt_ratio, "metadata_ratio=%d"},
|
||||||
@ -374,7 +376,8 @@ static const match_table_t tokens = {
|
|||||||
* reading in a new superblock is parsed here.
|
* reading in a new superblock is parsed here.
|
||||||
* XXX JDM: This needs to be cleaned up for remount.
|
* 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;
|
struct btrfs_fs_info *info = root->fs_info;
|
||||||
substring_t args[MAX_OPT_ARGS];
|
substring_t args[MAX_OPT_ARGS];
|
||||||
@ -394,8 +397,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
|
|||||||
else if (cache_gen)
|
else if (cache_gen)
|
||||||
btrfs_set_opt(info->mount_opt, SPACE_CACHE);
|
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)
|
if (!options)
|
||||||
goto out;
|
goto check;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* strsep changes the string, duplicate it because parse_options
|
* 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,
|
btrfs_clear_and_info(root, NOTREELOG,
|
||||||
"enabling tree log");
|
"enabling tree log");
|
||||||
break;
|
break;
|
||||||
|
case Opt_nologreplay:
|
||||||
|
btrfs_set_and_info(root, NOLOGREPLAY,
|
||||||
|
"disabling log replay at mount time");
|
||||||
|
break;
|
||||||
case Opt_flushoncommit:
|
case Opt_flushoncommit:
|
||||||
btrfs_set_and_info(root, FLUSHONCOMMIT,
|
btrfs_set_and_info(root, FLUSHONCOMMIT,
|
||||||
"turning on flush-on-commit");
|
"turning on flush-on-commit");
|
||||||
@ -797,6 +808,15 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
|
|||||||
break;
|
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:
|
out:
|
||||||
if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) &&
|
if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) &&
|
||||||
!btrfs_test_opt(root, 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");
|
seq_puts(seq, ",ssd");
|
||||||
if (btrfs_test_opt(root, NOTREELOG))
|
if (btrfs_test_opt(root, NOTREELOG))
|
||||||
seq_puts(seq, ",notreelog");
|
seq_puts(seq, ",notreelog");
|
||||||
|
if (btrfs_test_opt(root, NOLOGREPLAY))
|
||||||
|
seq_puts(seq, ",nologreplay");
|
||||||
if (btrfs_test_opt(root, FLUSHONCOMMIT))
|
if (btrfs_test_opt(root, FLUSHONCOMMIT))
|
||||||
seq_puts(seq, ",flushoncommit");
|
seq_puts(seq, ",flushoncommit");
|
||||||
if (btrfs_test_opt(root, DISCARD))
|
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) {
|
if (ret) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto restore;
|
goto restore;
|
||||||
|
Loading…
Reference in New Issue
Block a user