linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Anand Jain <anand.jain@oracle.com>
To: David Sterba <dsterba@suse.com>, linux-btrfs@vger.kernel.org
Subject: Re: [PATCH 05/13] btrfs-progs: two staged filesystem creation
Date: Wed, 24 Aug 2016 18:27:44 +0800	[thread overview]
Message-ID: <35455b29-a076-41ef-e8ee-ed001601395a@oracle.com> (raw)
In-Reply-To: <1471947917-5324-6-git-send-email-dsterba@suse.com>



On 08/23/2016 06:25 PM, David Sterba wrote:
> The filesystem existence on a device is manifested by the signature,
> during the mkfs process we write it first and then create other
> structures. Such filesystem is not valid and should not be registered
> during device scan nor listed among devices from blkid.
>
> This patch will introduce two staged creation. In the first phase, the
> signature is wrong, but recognized as a partially created filesystem (by
> open or scan helpers). Once we successfully create and write everything,
> we fixup the signature. At this point automated scanning should find
> a valid filesystem on all devices.
>
> We can also rely on the partially created filesystem to do better error
> handling during creation. We can just bail out and do not need to clean
> up.


  Looks good to me.

Reviewed-by: Anand Jain <anand.jain@oracle.com>

Thanks, Anand


> The partial signature is '!BHRfS_M', can be shown by
>
>   btrfs inspect-internal dump-super -F image
>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>  btrfs-convert.c |  7 +++++--
>  ctree.h         |  1 +
>  disk-io.c       | 35 +++++++++++++++++++++++++++++------
>  disk-io.h       | 11 ++++++++++-
>  mkfs.c          |  7 ++++++-
>  utils.c         | 10 ++++++++--
>  6 files changed, 59 insertions(+), 12 deletions(-)
>
> diff --git a/btrfs-convert.c b/btrfs-convert.c
> index a8852d612886..b34a413de5be 100644
> --- a/btrfs-convert.c
> +++ b/btrfs-convert.c
> @@ -2345,7 +2345,7 @@ static int do_convert(const char *devname, int datacsum, int packing,
>  	}
>
>  	root = open_ctree_fd(fd, devname, mkfs_cfg.super_bytenr,
> -			     OPEN_CTREE_WRITES);
> +			     OPEN_CTREE_WRITES | OPEN_CTREE_FS_PARTIAL);
>  	if (!root) {
>  		fprintf(stderr, "unable to open ctree\n");
>  		goto fail;
> @@ -2431,11 +2431,14 @@ static int do_convert(const char *devname, int datacsum, int packing,
>  	}
>  	is_btrfs = 1;
>
> -	root = open_ctree_fd(fd, devname, 0, OPEN_CTREE_WRITES);
> +	root = open_ctree_fd(fd, devname, 0,
> +			OPEN_CTREE_WRITES | OPEN_CTREE_FS_PARTIAL);
>  	if (!root) {
>  		fprintf(stderr, "unable to open ctree\n");
>  		goto fail;
>  	}
> +	root->fs_info->finalize_on_close = 1;
> +	close_ctree(root);
>  	close(fd);
>
>  	printf("conversion complete.\n");
> diff --git a/ctree.h b/ctree.h
> index 89e47abd9d14..d0569835d0a2 100644
> --- a/ctree.h
> +++ b/ctree.h
> @@ -1032,6 +1032,7 @@ struct btrfs_fs_info {
>  	unsigned int ignore_chunk_tree_error:1;
>  	unsigned int avoid_meta_chunk_alloc:1;
>  	unsigned int avoid_sys_chunk_alloc:1;
> +	unsigned int finalize_on_close:1;
>
>  	int (*free_extent_hook)(struct btrfs_trans_handle *trans,
>  				struct btrfs_root *root,
> diff --git a/disk-io.c b/disk-io.c
> index 4874f0689228..dd4a34142496 100644
> --- a/disk-io.c
> +++ b/disk-io.c
> @@ -1225,6 +1225,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
>  	struct extent_buffer *eb;
>  	int ret;
>  	int oflags;
> +	unsigned sbflags = SBREAD_DEFAULT;
>
>  	if (sb_bytenr == 0)
>  		sb_bytenr = BTRFS_SUPER_INFO_OFFSET;
> @@ -1247,9 +1248,18 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
>  	if (flags & OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR)
>  		fs_info->ignore_chunk_tree_error = 1;
>
> -	ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr,
> -		(flags & OPEN_CTREE_RECOVER_SUPER) ? SBREAD_RECOVER : SBREAD_DEFAULT,
> -		(flags & OPEN_CTREE_NO_DEVICES));
> +	if ((flags & OPEN_CTREE_RECOVER_SUPER)
> +	     && (flags & OPEN_CTREE_FS_PARTIAL)) {
> +		fprintf(stderr,
> +		    "cannot open a partially created filesystem for recovery");
> +		return NULL;
> +	}
> +
> +	if (flags & OPEN_CTREE_FS_PARTIAL)
> +		sbflags = SBREAD_PARTIAL;
> +
> +	ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr, sbflags,
> +			(flags & OPEN_CTREE_NO_DEVICES));
>  	if (ret)
>  		goto out;
>
> @@ -1272,7 +1282,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
>  				sb_bytenr, SBREAD_RECOVER);
>  	else
>  		ret = btrfs_read_dev_super(fp, disk_super, sb_bytenr,
> -				SBREAD_DEFAULT);
> +				sbflags);
>  	if (ret) {
>  		printk("No valid btrfs found\n");
>  		goto out_devices;
> @@ -1401,8 +1411,12 @@ static int check_super(struct btrfs_super_block *sb, unsigned sbflags)
>  	int csum_size;
>
>  	if (btrfs_super_magic(sb) != BTRFS_MAGIC) {
> -		error("superblock magic doesn't match");
> -		return -EIO;
> +		if (btrfs_super_magic(sb) == BTRFS_MAGIC_PARTIAL) {
> +			if (!(sbflags & SBREAD_PARTIAL)) {
> +				error("superblock magic doesn't match");
> +				return -EIO;
> +			}
> +		}
>  	}
>
>  	csum_type = btrfs_super_csum_type(sb);
> @@ -1747,6 +1761,15 @@ int close_ctree_fs_info(struct btrfs_fs_info *fs_info)
>  		write_ctree_super(trans, root);
>  		btrfs_free_transaction(root, trans);
>  	}
> +
> +	if (fs_info->finalize_on_close) {
> +		btrfs_set_super_magic(fs_info->super_copy, BTRFS_MAGIC);
> +		root->fs_info->finalize_on_close = 0;
> +		ret = write_all_supers(root);
> +		if (ret)
> +			fprintf(stderr,
> +				"failed to write new super block err %d\n", ret);
> +	}
>  	btrfs_free_block_groups(fs_info);
>
>  	free_fs_roots_tree(&fs_info->fs_root_tree);
> diff --git a/disk-io.h b/disk-io.h
> index 153ef1f49641..a73dede1e8d0 100644
> --- a/disk-io.h
> +++ b/disk-io.h
> @@ -61,7 +61,10 @@ enum btrfs_open_ctree_flags {
>  	 * It's useful for chunk corruption case.
>  	 * Makes no sense for open_ctree variants returning btrfs_root.
>  	 */
> -	OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR = (1 << 11)
> +	OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR = (1 << 11),
> +
> +	/* Allow to open a partially created filesystem */
> +	OPEN_CTREE_FS_PARTIAL = (1 << 12),
>  };
>
>  /*
> @@ -71,6 +74,12 @@ enum btrfs_read_sb_flags {
>  	SBREAD_DEFAULT		= 0,
>  	/* Reading superblock during recovery */
>  	SBREAD_RECOVER		= (1 << 0),
> +
> +	/*
> +	 * Read superblock with the fake signature, cannot be used with
> +	 * SBREAD_RECOVER
> +	 */
> +	SBREAD_PARTIAL		= (1 << 1),
>  };
>
>  static inline u64 btrfs_sb_offset(int mirror)
> diff --git a/mkfs.c b/mkfs.c
> index 0b081dd44457..ee5a30daff54 100644
> --- a/mkfs.c
> +++ b/mkfs.c
> @@ -1708,7 +1708,7 @@ int main(int argc, char **argv)
>  		exit(1);
>  	}
>
> -	root = open_ctree(file, 0, OPEN_CTREE_WRITES);
> +	root = open_ctree(file, 0, OPEN_CTREE_WRITES | OPEN_CTREE_FS_PARTIAL);
>  	if (!root) {
>  		error("open ctree failed");
>  		close(fd);
> @@ -1858,6 +1858,11 @@ int main(int argc, char **argv)
>  		list_all_devices(root);
>  	}
>
> +	/*
> +	 * The filesystem is now fully set up, commit the remaining changes and
> +	 * fix the signature as the last step before closing the devices.
> +	 */
> +	root->fs_info->finalize_on_close = 1;
>  out:
>  	ret = close_ctree(root);
>  	BUG_ON(ret);
> diff --git a/utils.c b/utils.c
> index e7195b53b015..cec7c738e088 100644
> --- a/utils.c
> +++ b/utils.c
> @@ -238,6 +238,9 @@ static inline int write_temp_super(int fd, struct btrfs_super_block *sb,
>   *
>   * For now sys chunk array will be empty and dev_item is empty too.
>   * They will be re-initialized at temp chunk tree setup.
> + *
> + * The superblock signature is not valid, denotes a partially created
> + * filesystem, needs to be finalized.
>   */
>  static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg,
>  			    u64 root_bytenr, u64 chunk_bytenr)
> @@ -276,7 +279,7 @@ static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg,
>
>  	btrfs_set_super_bytenr(super, cfg->super_bytenr);
>  	btrfs_set_super_num_devices(super, 1);
> -	btrfs_set_super_magic(super, BTRFS_MAGIC);
> +	btrfs_set_super_magic(super, BTRFS_MAGIC_PARTIAL);
>  	btrfs_set_super_generation(super, 1);
>  	btrfs_set_super_root(super, root_bytenr);
>  	btrfs_set_super_chunk_root(super, chunk_bytenr);
> @@ -1004,6 +1007,9 @@ static int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
>
>  /*
>   * @fs_uuid - if NULL, generates a UUID, returns back the new filesystem UUID
> + *
> + * The superblock signature is not valid, denotes a partially created
> + * filesystem, needs to be finalized.
>   */
>  int make_btrfs(int fd, struct btrfs_mkfs_config *cfg,
>  		struct btrfs_convert_context *cctx)
> @@ -1064,7 +1070,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg,
>
>  	btrfs_set_super_bytenr(&super, cfg->blocks[0]);
>  	btrfs_set_super_num_devices(&super, 1);
> -	btrfs_set_super_magic(&super, BTRFS_MAGIC);
> +	btrfs_set_super_magic(&super, BTRFS_MAGIC_PARTIAL);
>  	btrfs_set_super_generation(&super, 1);
>  	btrfs_set_super_root(&super, cfg->blocks[1]);
>  	btrfs_set_super_chunk_root(&super, cfg->blocks[3]);
>

  reply	other threads:[~2016-08-24 10:27 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
2016-08-23 10:25 ` [PATCH 01/13] btrfs-progs: pass OPEN_CTREE flags as unsigned David Sterba
2016-08-24 10:24   ` Anand Jain
2016-08-23 10:25 ` [PATCH 02/13] btrfs-progs: make superblock reading/scanning api more generic David Sterba
2016-08-23 10:25 ` [PATCH 03/13] btrfs-progs: introduce signature for a partially set up filesystem David Sterba
2016-08-23 10:25 ` [PATCH 04/13] btrfs-progs: mkfs: do not scan partially initialized devices David Sterba
2016-08-23 10:25 ` [PATCH 05/13] btrfs-progs: two staged filesystem creation David Sterba
2016-08-24 10:27   ` Anand Jain [this message]
2016-08-23 10:25 ` [PATCH 06/13] btrfs-progs: mkfs: return errors from block group creation functions David Sterba
2016-08-23 10:25 ` [PATCH 07/13] btrfs-progs: mkfs: improve error handling in main() David Sterba
2016-08-23 10:25 ` [PATCH 08/13] btrfs-progs: mkfs: improve error handling in recow_roots David Sterba
2016-08-23 10:25 ` [PATCH 09/13] btrfs-progs: document all btrfs_open_ctree_flags David Sterba
2016-08-23 10:25 ` [PATCH 10/13] btrfs-progs: mkfs: switch BUG_ON to error handling in traverse_directory David Sterba
2016-08-23 10:25 ` [PATCH 11/13] btrfs-progs: mkfs: handle and report transaction commit failures David Sterba
2016-08-23 10:25 ` [PATCH 12/13] btrfs-progs: mkfs: help and usage now to to stdout David Sterba
2016-08-23 10:25 ` [PATCH 13/13] btrfs-progs: mkfs: clean up make_image David Sterba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=35455b29-a076-41ef-e8ee-ed001601395a@oracle.com \
    --to=anand.jain@oracle.com \
    --cc=dsterba@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).