diff mbox

[v2] btrfs: Introduce new mount option to disable tree log replay

Message ID 1449555033-25075-1-git-send-email-quwenruo@cn.fujitsu.com (mailing list archive)
State Superseded
Headers show

Commit Message

Qu Wenruo Dec. 8, 2015, 6:10 a.m. UTC
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>
---
v2:
  Make RO check mandatory for btrfs_parse_options().
  Add btrfs_show_options() support for nologreplay.

  Document for btrfs-mount(5) will follow after the patch being merged.
---
 Documentation/filesystems/btrfs.txt |  7 +++++++
 fs/btrfs/ctree.h                    |  4 +++-
 fs/btrfs/disk-io.c                  |  7 ++++---
 fs/btrfs/super.c                    | 29 +++++++++++++++++++++++++----
 4 files changed, 39 insertions(+), 8 deletions(-)

Comments

Roman Mamedov Dec. 8, 2015, 6:31 a.m. UTC | #1
On Tue,  8 Dec 2015 14:10:33 +0800
Qu Wenruo <quwenruo@cn.fujitsu.com> wrote:

> Introduce a new mount option "nologreplay" to co-operate with "ro" mount
> option to get real readonly mount, like "norecovery" in ext* and xfs.

Maybe name it "norecovery" too, for simplicity and consistency?

The actual effect of "norecovery" in ext* and xfs is to also disable log
replay, but that's an under-the-hood detail not relevant to the user.

---
Mount options for ext3

       norecovery/noload
              Don't load the journal on mounting.  Note that if the filesystem
              was not unmounted cleanly, skipping the journal replay will lead
              to  the  filesystem  containing inconsistencies that can lead to
              any number of problems.
---
Mount options for xfs

       norecovery
              The filesystem will be mounted without running log recovery.  If
              the filesystem was not cleanly unmounted, it  is  likely  to  be
              inconsistent  when  mounted  in  norecovery mode.  Some files or
              directories may not be accessible because of this.   Filesystems
              mounted  norecovery  must be mounted read-only or the mount will
              fail.
---
Qu Wenruo Dec. 8, 2015, 6:50 a.m. UTC | #2
Roman Mamedov wrote on 2015/12/08 11:31 +0500:
> On Tue,  8 Dec 2015 14:10:33 +0800
> Qu Wenruo <quwenruo@cn.fujitsu.com> wrote:
>
>> Introduce a new mount option "nologreplay" to co-operate with "ro" mount
>> option to get real readonly mount, like "norecovery" in ext* and xfs.
>
> Maybe name it "norecovery" too, for simplicity and consistency?

That's also our first idea.
But the sad fact is, btrfs already has a mount option called "recovery".

So "norecovery" here will just be considered as a mount option to 
disable "recovery", and that will make things more confusing.

And finally we choose the name "nologreplay".

Thanks,
Qu

>
> The actual effect of "norecovery" in ext* and xfs is to also disable log
> replay, but that's an under-the-hood detail not relevant to the user.
>
> ---
> Mount options for ext3
>
>         norecovery/noload
>                Don't load the journal on mounting.  Note that if the filesystem
>                was not unmounted cleanly, skipping the journal replay will lead
>                to  the  filesystem  containing inconsistencies that can lead to
>                any number of problems.
> ---
> Mount options for xfs
>
>         norecovery
>                The filesystem will be mounted without running log recovery.  If
>                the filesystem was not cleanly unmounted, it  is  likely  to  be
>                inconsistent  when  mounted  in  norecovery mode.  Some files or
>                directories may not be accessible because of this.   Filesystems
>                mounted  norecovery  must be mounted read-only or the mount will
>                fail.
> ---
>


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chandan Rajendra Dec. 8, 2015, 10:06 a.m. UTC | #3
On Tuesday 08 Dec 2015 14:10:33 Qu Wenruo wrote:
> 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>
> ---
> v2:
>   Make RO check mandatory for btrfs_parse_options().
>   Add btrfs_show_options() support for nologreplay.
> 
>   Document for btrfs-mount(5) will follow after the patch being merged.
> ---
>  Documentation/filesystems/btrfs.txt |  7 +++++++
>  fs/btrfs/ctree.h                    |  4 +++-
>  fs/btrfs/disk-io.c                  |  7 ++++---
>  fs/btrfs/super.c                    | 29 +++++++++++++++++++++++++----
>  4 files changed, 39 insertions(+), 8 deletions(-)
> 
> diff --git a/Documentation/filesystems/btrfs.txt
> b/Documentation/filesystems/btrfs.txt index c772b47..7ad5b93 100644
> --- a/Documentation/filesystems/btrfs.txt
> +++ b/Documentation/filesystems/btrfs.txt
> @@ -168,6 +168,13 @@ Options with (*) are default options and will not show
> in the mount options. notreelog
>  	Enable/disable the tree logging used for fsync and O_SYNC writes.
> 
> +  nologreplay
> +	Disable the log tree replay at mount time to prevent devices get
> +	modified. Must be use with 'ro' mount option.
> +	A filesystem mounted with the 'nologreplay' option cannot
> +	transition to a read-write mount via remount,rw - the filesystem
> +	must be unmounted and remounted if read-write access is desired.
> +

May be the following is slightly better ...

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 the
'nologreplay' 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.

Aside from above, everything else looks good to me.

Reviewed-by: Chandan Rajendra <chandan@linux.vnet.ibm.com>
Austin S. Hemmelgarn Dec. 8, 2015, 4:24 p.m. UTC | #4
On 2015-12-08 01:10, Qu Wenruo wrote:
> 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>
> ---
> v2:
>    Make RO check mandatory for btrfs_parse_options().
>    Add btrfs_show_options() support for nologreplay.
>
>    Document for btrfs-mount(5) will follow after the patch being merged.

Same set of tests I ran against the last version, still no issues, so:
Tested-by: Austin S. Hemmelgarn
Qu Wenruo Dec. 10, 2015, 1:24 a.m. UTC | #5
Chandan Rajendra wrote on 2015/12/08 15:36 +0530:
> On Tuesday 08 Dec 2015 14:10:33 Qu Wenruo wrote:
>> 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>
>> ---
>> v2:
>>    Make RO check mandatory for btrfs_parse_options().
>>    Add btrfs_show_options() support for nologreplay.
>>
>>    Document for btrfs-mount(5) will follow after the patch being merged.
>> ---
>>   Documentation/filesystems/btrfs.txt |  7 +++++++
>>   fs/btrfs/ctree.h                    |  4 +++-
>>   fs/btrfs/disk-io.c                  |  7 ++++---
>>   fs/btrfs/super.c                    | 29 +++++++++++++++++++++++++----
>>   4 files changed, 39 insertions(+), 8 deletions(-)
>>
>> diff --git a/Documentation/filesystems/btrfs.txt
>> b/Documentation/filesystems/btrfs.txt index c772b47..7ad5b93 100644
>> --- a/Documentation/filesystems/btrfs.txt
>> +++ b/Documentation/filesystems/btrfs.txt
>> @@ -168,6 +168,13 @@ Options with (*) are default options and will not show
>> in the mount options. notreelog
>>   	Enable/disable the tree logging used for fsync and O_SYNC writes.
>>
>> +  nologreplay
>> +	Disable the log tree replay at mount time to prevent devices get
>> +	modified. Must be use with 'ro' mount option.
>> +	A filesystem mounted with the 'nologreplay' option cannot
>> +	transition to a read-write mount via remount,rw - the filesystem
>> +	must be unmounted and remounted if read-write access is desired.
>> +
>
> May be the following is slightly better ...
>
> 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 the
> 'nologreplay' 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.

Thanks for the review and advice.

Since I'm not a native English speaker, I'll follow your advice.
(Yeah, remount in my patch is confusing.)

I'll update it to v3 with Document update only

Thank,
Qu
>
> Aside from above, everything else looks good to me.
>
> Reviewed-by: Chandan Rajendra <chandan@linux.vnet.ibm.com>
>


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/filesystems/btrfs.txt b/Documentation/filesystems/btrfs.txt
index c772b47..7ad5b93 100644
--- a/Documentation/filesystems/btrfs.txt
+++ b/Documentation/filesystems/btrfs.txt
@@ -168,6 +168,13 @@  Options with (*) are default options and will not show in the mount options.
   notreelog
 	Enable/disable the tree logging used for fsync and O_SYNC writes.
 
+  nologreplay
+	Disable the log tree replay at mount time to prevent devices get
+	modified. Must be use with 'ro' mount option.
+	A filesystem mounted with the 'nologreplay' option cannot
+	transition to a read-write mount via remount,rw - the filesystem
+	must be unmounted and remounted if read-write access is desired.
+
   recovery
 	Enable autorecovery attempts if a bad tree root is found at mount time.
 	Currently this scans a list of several previous tree roots and tries to
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index a0165c6..c54ff25 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2184,6 +2184,7 @@  struct btrfs_ioctl_defrag_range_args {
 #define BTRFS_MOUNT_RESCAN_UUID_TREE	(1 << 23)
 #define BTRFS_MOUNT_FRAGMENT_DATA	(1 << 24)
 #define BTRFS_MOUNT_FRAGMENT_METADATA	(1 << 25)
+#define BTRFS_MOUNT_NOLOGREPLAY		(1 << 26)
 
 #define BTRFS_DEFAULT_COMMIT_INTERVAL	(30)
 #define BTRFS_DEFAULT_MAX_INLINE	(8192)
@@ -4070,7 +4071,8 @@  void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
 ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 
 /* 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);
 
 #ifdef CONFIG_PRINTK
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 1eb0839..617bf4f 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2711,7 +2711,7 @@  int open_ctree(struct super_block *sb,
 	 */
 	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) {
 		err = ret;
 		goto fail_alloc;
@@ -3009,8 +3009,9 @@  retry_root_backup:
 	if (ret)
 		goto fail_trans_kthread;
 
-	/* do not make disk changes in broken FS */
-	if (btrfs_super_log_root(disk_super) != 0) {
+	/* do not make disk changes in broken FS or nologreplay is given */
+	if (btrfs_super_log_root(disk_super) != 0 &&
+	    !btrfs_test_opt(tree_root, NOLOGREPLAY)) {
 		ret = btrfs_replay_log(fs_info, fs_devices);
 		if (ret) {
 			err = ret;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 24154e4..55989cb 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -302,7 +302,7 @@  enum {
 	Opt_check_integrity_print_mask, Opt_fatal_errors, Opt_rescan_uuid_tree,
 	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_datasum, Opt_treelog, Opt_noinode_cache, Opt_nologreplay,
 #ifdef CONFIG_BTRFS_DEBUG
 	Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
 #endif
@@ -334,6 +334,7 @@  static 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"},
@@ -371,7 +372,8 @@  static 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];
@@ -386,8 +388,12 @@  int btrfs_parse_options(struct btrfs_root *root, char *options)
 	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
@@ -587,6 +593,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");
@@ -753,6 +763,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 (!ret && btrfs_test_opt(root, SPACE_CACHE))
 		btrfs_info(root->fs_info, "disk space caching is enabled");
@@ -1154,6 +1173,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))
@@ -1637,7 +1658,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;