All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups
@ 2016-08-23 10:25 David Sterba
  2016-08-23 10:25 ` [PATCH 01/13] btrfs-progs: pass OPEN_CTREE flags as unsigned David Sterba
                   ` (12 more replies)
  0 siblings, 13 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Hi,

this series mainly improves error handling in mkfs and convert, plus the
collaterals. There were too many BUG_ONs, now there are 0 in mkfs.c. There's
still work to do, eg. in the generic functions.

The improvement idea is to be able to safely leave around an unfinished
filesystem image, so the error handling is just "report & return". The signature
is intentionally bogus until the entire filesystem is constructed.

This is now in devel.

David Sterba (13):
  btrfs-progs: pass OPEN_CTREE flags as unsigned
  btrfs-progs: make superblock reading/scanning api more generic
  btrfs-progs: introduce signature for a partially set up filesystem
  btrfs-progs: mkfs: do not scan partially initialized devices
  btrfs-progs: two staged filesystem creation
  btrfs-progs: mkfs: return errors from block group creation functions
  btrfs-progs: mkfs: improve error handling in main()
  btrfs-progs: mkfs: improve error handling in recow_roots
  btrfs-progs: document all btrfs_open_ctree_flags
  btrfs-progs: mkfs: switch BUG_ON to error handling in
    traverse_directory
  btrfs-progs: mkfs: handle and report transaction commit failures
  btrfs-progs: mkfs: help and usage now to to stdout
  btrfs-progs: mkfs: clean up make_image

 btrfs-convert.c   |   7 +-
 btrfstune.c       |   2 +-
 chunk-recover.c   |   8 +-
 cmds-check.c      |   2 +-
 cmds-filesystem.c |   2 +-
 ctree.h           |   7 ++
 disk-io.c         |  66 ++++++++++-----
 disk-io.h         |  69 ++++++++++-----
 mkfs.c            | 246 ++++++++++++++++++++++++++++++++++++------------------
 super-recover.c   |   3 +-
 utils.c           |  22 +++--
 volumes.c         |   4 +-
 volumes.h         |   2 +-
 13 files changed, 299 insertions(+), 141 deletions(-)

-- 
2.7.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 01/13] btrfs-progs: pass OPEN_CTREE flags as unsigned
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
@ 2016-08-23 10:25 ` 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
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

As we're passing a set of flags, the enum type is not appropriate.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 btrfstune.c  |  2 +-
 cmds-check.c |  2 +-
 disk-io.c    | 12 ++++++------
 disk-io.h    |  8 ++++----
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/btrfstune.c b/btrfstune.c
index ac559fb9e3de..93b25e8cece8 100644
--- a/btrfstune.c
+++ b/btrfstune.c
@@ -389,7 +389,7 @@ static void print_usage(void)
 int main(int argc, char *argv[])
 {
 	struct btrfs_root *root;
-	enum btrfs_open_ctree_flags ctree_flags = OPEN_CTREE_WRITES;
+	unsigned ctree_flags = OPEN_CTREE_WRITES;
 	int success = 0;
 	int total = 0;
 	int seeding_flag = 0;
diff --git a/cmds-check.c b/cmds-check.c
index fc15ce98f4bb..0ddfd24a4d8e 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -11178,7 +11178,7 @@ int cmd_check(int argc, char **argv)
 	int readonly = 0;
 	int qgroup_report = 0;
 	int qgroups_repaired = 0;
-	enum btrfs_open_ctree_flags ctree_flags = OPEN_CTREE_EXCLUSIVE;
+	unsigned ctree_flags = OPEN_CTREE_EXCLUSIVE;
 
 	while(1) {
 		int c;
diff --git a/disk-io.c b/disk-io.c
index 3647ecca7e63..279e38b74c39 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -932,7 +932,7 @@ static int find_best_backup_root(struct btrfs_super_block *super)
 }
 
 static int setup_root_or_create_block(struct btrfs_fs_info *fs_info,
-				      enum btrfs_open_ctree_flags flags,
+				      unsigned flags,
 				      struct btrfs_root *info_root,
 				      u64 objectid, char *str)
 {
@@ -961,7 +961,7 @@ static int setup_root_or_create_block(struct btrfs_fs_info *fs_info,
 }
 
 int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
-			  enum btrfs_open_ctree_flags flags)
+			  unsigned flags)
 {
 	struct btrfs_super_block *sb = fs_info->super_copy;
 	struct btrfs_root *root;
@@ -1217,7 +1217,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
 					     u64 sb_bytenr,
 					     u64 root_tree_bytenr,
 					     u64 chunk_root_bytenr,
-					     enum btrfs_open_ctree_flags flags)
+					     unsigned flags)
 {
 	struct btrfs_fs_info *fs_info;
 	struct btrfs_super_block *disk_super;
@@ -1323,7 +1323,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
 struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
 					 u64 sb_bytenr, u64 root_tree_bytenr,
 					 u64 chunk_root_bytenr,
-					 enum btrfs_open_ctree_flags flags)
+					 unsigned flags)
 {
 	int fp;
 	int ret;
@@ -1356,7 +1356,7 @@ struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
 }
 
 struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
-			      enum btrfs_open_ctree_flags flags)
+			      unsigned flags)
 {
 	struct btrfs_fs_info *info;
 
@@ -1371,7 +1371,7 @@ struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
 }
 
 struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
-				 enum btrfs_open_ctree_flags flags)
+				 unsigned flags)
 {
 	struct btrfs_fs_info *info;
 
diff --git a/disk-io.h b/disk-io.h
index d6fb9822614f..9ebb2366b933 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -103,7 +103,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info);
 struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr);
 int btrfs_check_fs_compatibility(struct btrfs_super_block *sb, int writable);
 int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
-			  enum btrfs_open_ctree_flags flags);
+			  unsigned flags);
 void btrfs_release_all_roots(struct btrfs_fs_info *fs_info);
 void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info);
 int btrfs_scan_fs_devices(int fd, const char *path,
@@ -113,13 +113,13 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
 			  u64 chunk_root_bytenr);
 
 struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
-			      enum btrfs_open_ctree_flags flags);
+			      unsigned flags);
 struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
-				 enum btrfs_open_ctree_flags flags);
+				 unsigned flags);
 struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
 					 u64 sb_bytenr, u64 root_tree_bytenr,
 					 u64 chunk_root_bytenr,
-					 enum btrfs_open_ctree_flags flags);
+					 unsigned flags);
 int close_ctree_fs_info(struct btrfs_fs_info *fs_info);
 static inline int close_ctree(struct btrfs_root *root)
 {
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 02/13] btrfs-progs: make superblock reading/scanning api more generic
  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-23 10:25 ` David Sterba
  2016-08-23 10:25 ` [PATCH 03/13] btrfs-progs: introduce signature for a partially set up filesystem David Sterba
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

We'll add more modes that affect scanning.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 chunk-recover.c   |  8 +++++---
 cmds-filesystem.c |  2 +-
 disk-io.c         | 25 +++++++++++++------------
 disk-io.h         | 13 +++++++++++--
 super-recover.c   |  3 ++-
 utils.c           |  5 +++--
 volumes.c         |  4 ++--
 volumes.h         |  2 +-
 8 files changed, 38 insertions(+), 24 deletions(-)

diff --git a/chunk-recover.c b/chunk-recover.c
index 085e9a256ea4..4a081db2de33 100644
--- a/chunk-recover.c
+++ b/chunk-recover.c
@@ -1470,7 +1470,8 @@ open_ctree_with_broken_chunk(struct recover_control *rc)
 
 	disk_super = fs_info->super_copy;
 	ret = btrfs_read_dev_super(fs_info->fs_devices->latest_bdev,
-				   disk_super, fs_info->super_bytenr, 1);
+				   disk_super, fs_info->super_bytenr,
+				   SBREAD_RECOVER);
 	if (ret) {
 		fprintf(stderr, "No valid btrfs found\n");
 		goto out_devices;
@@ -1531,7 +1532,8 @@ static int recover_prepare(struct recover_control *rc, char *path)
 	}
 
 	sb = (struct btrfs_super_block*)buf;
-	ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET, 1);
+	ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET,
+			SBREAD_RECOVER);
 	if (ret) {
 		fprintf(stderr, "read super block error\n");
 		goto out_close_fd;
@@ -1550,7 +1552,7 @@ static int recover_prepare(struct recover_control *rc, char *path)
 		goto out_close_fd;
 	}
 
-	ret = btrfs_scan_fs_devices(fd, path, &fs_devices, 0, 1, 0);
+	ret = btrfs_scan_fs_devices(fd, path, &fs_devices, 0, SBREAD_RECOVER, 0);
 	if (ret)
 		goto out_close_fd;
 
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 00e4bfe41c86..76ea82edf23c 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -524,7 +524,7 @@ static int dev_to_fsid(char *dev, __u8 *fsid)
 
 	disk_super = (struct btrfs_super_block *)buf;
 	ret = btrfs_read_dev_super(fd, disk_super,
-				   BTRFS_SUPER_INFO_OFFSET, 0);
+				   BTRFS_SUPER_INFO_OFFSET, SBREAD_DEFAULT);
 	if (ret)
 		goto out;
 
diff --git a/disk-io.c b/disk-io.c
index 279e38b74c39..4874f0689228 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -1114,7 +1114,7 @@ void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info)
 
 int btrfs_scan_fs_devices(int fd, const char *path,
 			  struct btrfs_fs_devices **fs_devices,
-			  u64 sb_bytenr, int super_recover,
+			  u64 sb_bytenr, unsigned sbflags,
 			  int skip_devices)
 {
 	u64 total_devs;
@@ -1136,7 +1136,7 @@ int btrfs_scan_fs_devices(int fd, const char *path,
 	}
 
 	ret = btrfs_scan_one_device(fd, path, fs_devices,
-				    &total_devs, sb_bytenr, super_recover);
+				    &total_devs, sb_bytenr, sbflags);
 	if (ret) {
 		fprintf(stderr, "No valid Btrfs found on %s\n", path);
 		return ret;
@@ -1248,8 +1248,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
 		fs_info->ignore_chunk_tree_error = 1;
 
 	ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr,
-				    (flags & OPEN_CTREE_RECOVER_SUPER),
-				    (flags & OPEN_CTREE_NO_DEVICES));
+		(flags & OPEN_CTREE_RECOVER_SUPER) ? SBREAD_RECOVER : SBREAD_DEFAULT,
+		(flags & OPEN_CTREE_NO_DEVICES));
 	if (ret)
 		goto out;
 
@@ -1268,10 +1268,11 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
 
 	disk_super = fs_info->super_copy;
 	if (flags & OPEN_CTREE_RECOVER_SUPER)
-		ret = btrfs_read_dev_super(fs_devices->latest_bdev,
-					   disk_super, sb_bytenr, 1);
+		ret = btrfs_read_dev_super(fs_devices->latest_bdev, disk_super,
+				sb_bytenr, SBREAD_RECOVER);
 	else
-		ret = btrfs_read_dev_super(fp, disk_super, sb_bytenr, 0);
+		ret = btrfs_read_dev_super(fp, disk_super, sb_bytenr,
+				SBREAD_DEFAULT);
 	if (ret) {
 		printk("No valid btrfs found\n");
 		goto out_devices;
@@ -1392,7 +1393,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
  * - number of devices   - something sane
  * - sys array size      - maximum
  */
-static int check_super(struct btrfs_super_block *sb)
+static int check_super(struct btrfs_super_block *sb, unsigned sbflags)
 {
 	char result[BTRFS_CSUM_SIZE];
 	u32 crc;
@@ -1533,7 +1534,7 @@ static int check_super(struct btrfs_super_block *sb)
 }
 
 int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
-			 int super_recover)
+			 unsigned sbflags)
 {
 	u8 fsid[BTRFS_FSID_SIZE];
 	int fsid_is_initialized = 0;
@@ -1541,7 +1542,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
 	struct btrfs_super_block *buf = (struct btrfs_super_block *)tmp;
 	int i;
 	int ret;
-	int max_super = super_recover ? BTRFS_SUPER_MIRROR_MAX : 1;
+	int max_super = sbflags & SBREAD_RECOVER ? BTRFS_SUPER_MIRROR_MAX : 1;
 	u64 transid = 0;
 	u64 bytenr;
 
@@ -1553,7 +1554,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
 		if (btrfs_super_bytenr(buf) != sb_bytenr)
 			return -1;
 
-		if (check_super(buf))
+		if (check_super(buf, sbflags))
 			return -1;
 		memcpy(sb, buf, BTRFS_SUPER_INFO_SIZE);
 		return 0;
@@ -1577,7 +1578,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
 		/* if magic is NULL, the device was removed */
 		if (btrfs_super_magic(buf) == 0 && i == 0)
 			break;
-		if (check_super(buf))
+		if (check_super(buf, sbflags))
 			continue;
 
 		if (!fsid_is_initialized) {
diff --git a/disk-io.h b/disk-io.h
index 9ebb2366b933..153ef1f49641 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -64,6 +64,15 @@ enum btrfs_open_ctree_flags {
 	OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR = (1 << 11)
 };
 
+/*
+ * Modes of superblock access
+ */
+enum btrfs_read_sb_flags {
+	SBREAD_DEFAULT		= 0,
+	/* Reading superblock during recovery */
+	SBREAD_RECOVER		= (1 << 0),
+};
+
 static inline u64 btrfs_sb_offset(int mirror)
 {
 	u64 start = 16 * 1024;
@@ -108,7 +117,7 @@ void btrfs_release_all_roots(struct btrfs_fs_info *fs_info);
 void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info);
 int btrfs_scan_fs_devices(int fd, const char *path,
 			  struct btrfs_fs_devices **fs_devices, u64 sb_bytenr,
-			  int super_recover, int skip_devices);
+			  unsigned sbflags, int skip_devices);
 int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
 			  u64 chunk_root_bytenr);
 
@@ -132,7 +141,7 @@ int write_all_supers(struct btrfs_root *root);
 int write_ctree_super(struct btrfs_trans_handle *trans,
 		      struct btrfs_root *root);
 int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
-			 int super_recover);
+		unsigned sbflags);
 int btrfs_map_bh_to_logical(struct btrfs_root *root, struct extent_buffer *bh,
 			    u64 logical);
 struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
diff --git a/super-recover.c b/super-recover.c
index 88ecdee83e14..1dc3fc7d12e6 100644
--- a/super-recover.c
+++ b/super-recover.c
@@ -279,7 +279,8 @@ int btrfs_recover_superblocks(const char *dname,
 	}
 	init_recover_superblock(&recover);
 
-	ret = btrfs_scan_fs_devices(fd, dname, &recover.fs_devices, 0, 1, 0);
+	ret = btrfs_scan_fs_devices(fd, dname, &recover.fs_devices, 0,
+			SBREAD_RECOVER, 0);
 	close(fd);
 	if (ret) {
 		ret = 1;
diff --git a/utils.c b/utils.c
index 79bf946614c2..8be0e7537f8f 100644
--- a/utils.c
+++ b/utils.c
@@ -2272,7 +2272,7 @@ int check_mounted_where(int fd, const char *file, char *where, int size,
 
 	/* scan the initial device */
 	ret = btrfs_scan_one_device(fd, file, &fs_devices_mnt,
-				    &total_devs, BTRFS_SUPER_INFO_OFFSET, 0);
+		    &total_devs, BTRFS_SUPER_INFO_OFFSET, SBREAD_DEFAULT);
 	is_btrfs = (ret >= 0);
 
 	/* scan other devices */
@@ -3419,7 +3419,8 @@ int btrfs_scan_lblkid(void)
 			continue;
 		}
 		ret = btrfs_scan_one_device(fd, path, &tmp_devices,
-				&num_devices, BTRFS_SUPER_INFO_OFFSET, 0);
+				&num_devices, BTRFS_SUPER_INFO_OFFSET,
+				SBREAD_DEFAULT);
 		if (ret) {
 			error("cannot scan %s: %s", path, strerror(-ret));
 			close (fd);
diff --git a/volumes.c b/volumes.c
index a356d740cf44..9a5580ae6a5c 100644
--- a/volumes.c
+++ b/volumes.c
@@ -251,7 +251,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int flags)
 
 int btrfs_scan_one_device(int fd, const char *path,
 			  struct btrfs_fs_devices **fs_devices_ret,
-			  u64 *total_devs, u64 super_offset, int super_recover)
+			  u64 *total_devs, u64 super_offset, unsigned sbflags)
 {
 	struct btrfs_super_block *disk_super;
 	char buf[BTRFS_SUPER_INFO_SIZE];
@@ -259,7 +259,7 @@ int btrfs_scan_one_device(int fd, const char *path,
 	u64 devid;
 
 	disk_super = (struct btrfs_super_block *)buf;
-	ret = btrfs_read_dev_super(fd, disk_super, super_offset, super_recover);
+	ret = btrfs_read_dev_super(fd, disk_super, super_offset, sbflags);
 	if (ret < 0)
 		return -EIO;
 	devid = btrfs_stack_device_id(&disk_super->dev_item);
diff --git a/volumes.h b/volumes.h
index d88e1cf01abe..af7182b87cba 100644
--- a/volumes.h
+++ b/volumes.h
@@ -210,7 +210,7 @@ int btrfs_update_device(struct btrfs_trans_handle *trans,
 			struct btrfs_device *device);
 int btrfs_scan_one_device(int fd, const char *path,
 			  struct btrfs_fs_devices **fs_devices_ret,
-			  u64 *total_devs, u64 super_offset, int super_recover);
+			  u64 *total_devs, u64 super_offset, unsigned sbflags);
 int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len);
 struct list_head *btrfs_scanned_uuids(void);
 int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 03/13] btrfs-progs: introduce signature for a partially set up filesystem
  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-23 10:25 ` [PATCH 02/13] btrfs-progs: make superblock reading/scanning api more generic David Sterba
@ 2016-08-23 10:25 ` David Sterba
  2016-08-23 10:25 ` [PATCH 04/13] btrfs-progs: mkfs: do not scan partially initialized devices David Sterba
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Currently the superblock is created first, with a valid signaure, but
the rest of the filesystem is missing. When the creation process is
interrupted, the filesystem still might be considered as valid.

To prevent that, create the filesytem with an invalid signature that
would be still recognized during the mkfs process, and finalize at the
end.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 ctree.h | 6 ++++++
 utils.c | 7 ++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/ctree.h b/ctree.h
index b9fb732c0d40..89e47abd9d14 100644
--- a/ctree.h
+++ b/ctree.h
@@ -40,6 +40,12 @@ struct btrfs_trans_handle;
 struct btrfs_free_space_ctl;
 #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */
 
+/*
+ * Fake signature for an unfinalized filesystem, structures might be partially
+ * created or missing.
+ */
+#define BTRFS_MAGIC_PARTIAL 0x4D5F536652484221ULL /* ascii !BHRfS_M, no null */
+
 #define BTRFS_MAX_MIRRORS 3
 
 #define BTRFS_MAX_LEVEL 8
diff --git a/utils.c b/utils.c
index 8be0e7537f8f..e7195b53b015 100644
--- a/utils.c
+++ b/utils.c
@@ -2400,7 +2400,12 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
 
 	ret = 0;
 	disk_super = (struct btrfs_super_block *)buf;
-	if (btrfs_super_magic(disk_super) != BTRFS_MAGIC)
+	/*
+	 * Accept devices from the same filesystem, allow partially created
+	 * structures.
+	 */
+	if (btrfs_super_magic(disk_super) != BTRFS_MAGIC &&
+			btrfs_super_magic(disk_super) != BTRFS_MAGIC_PARTIAL)
 		goto brelse;
 
 	if (!memcmp(disk_super->fsid, root->fs_info->super_copy->fsid,
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 04/13] btrfs-progs: mkfs: do not scan partially initialized devices
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (2 preceding siblings ...)
  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 ` David Sterba
  2016-08-23 10:25 ` [PATCH 05/13] btrfs-progs: two staged filesystem creation David Sterba
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

We call scan ioctl on the devices too early, when most of the filesystem
structures are not yet created. Move the registration to the end, after
the filesystem gets closed.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/mkfs.c b/mkfs.c
index 1f209b54ff79..0b081dd44457 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1748,9 +1748,6 @@ int main(int argc, char **argv)
 		exit(1);
 	}
 
-	if (is_block_device(file) == 1)
-		btrfs_register_one_device(file);
-
 	if (dev_cnt == 0)
 		goto raid_groups;
 
@@ -1796,9 +1793,6 @@ int main(int argc, char **argv)
 			printf("adding device %s id %llu\n", file,
 				(unsigned long long)device->devid);
 		}
-
-		if (is_block_device(file) == 1)
-			btrfs_register_one_device(file);
 	}
 
 raid_groups:
@@ -1867,6 +1861,15 @@ int main(int argc, char **argv)
 out:
 	ret = close_ctree(root);
 	BUG_ON(ret);
+
+	optind = saved_optind;
+	dev_cnt = argc - optind;
+	while (dev_cnt-- > 0) {
+		file = argv[optind++];
+		if (is_block_device(file) == 1)
+			btrfs_register_one_device(file);
+	}
+
 	btrfs_close_all_devices();
 	free(label);
 	return 0;
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 05/13] btrfs-progs: two staged filesystem creation
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (3 preceding siblings ...)
  2016-08-23 10:25 ` [PATCH 04/13] btrfs-progs: mkfs: do not scan partially initialized devices David Sterba
@ 2016-08-23 10:25 ` David Sterba
  2016-08-24 10:27   ` Anand Jain
  2016-08-23 10:25 ` [PATCH 06/13] btrfs-progs: mkfs: return errors from block group creation functions David Sterba
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

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.

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]);
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 06/13] btrfs-progs: mkfs: return errors from block group creation functions
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (4 preceding siblings ...)
  2016-08-23 10:25 ` [PATCH 05/13] btrfs-progs: two staged filesystem creation David Sterba
@ 2016-08-23 10:25 ` David Sterba
  2016-08-23 10:25 ` [PATCH 07/13] btrfs-progs: mkfs: improve error handling in main() David Sterba
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

No more BUG_ONs, we don't care about cleanup as the filesystem is
supposed to be marked as partial.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 75 ++++++++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 48 insertions(+), 27 deletions(-)

diff --git a/mkfs.c b/mkfs.c
index ee5a30daff54..b2baf47bb595 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -79,7 +79,8 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
 				     BTRFS_FIRST_CHUNK_TREE_OBJECTID,
 				     0, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
 	allocation->system += BTRFS_MKFS_SYSTEM_GROUP_SIZE;
-	BUG_ON(ret);
+	if (ret)
+		return ret;
 
 	if (mixed) {
 		ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
@@ -90,13 +91,15 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
 			error("no space to allocate data/metadata chunk");
 			goto err;
 		}
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 		ret = btrfs_make_block_group(trans, root, 0,
 					     BTRFS_BLOCK_GROUP_METADATA |
 					     BTRFS_BLOCK_GROUP_DATA,
 					     BTRFS_FIRST_CHUNK_TREE_OBJECTID,
 					     chunk_start, chunk_size);
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 		allocation->mixed += chunk_size;
 	} else {
 		ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
@@ -106,17 +109,19 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
 			error("no space to allocate metadata chunk");
 			goto err;
 		}
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 		ret = btrfs_make_block_group(trans, root, 0,
 					     BTRFS_BLOCK_GROUP_METADATA,
 					     BTRFS_FIRST_CHUNK_TREE_OBJECTID,
 					     chunk_start, chunk_size);
 		allocation->metadata += chunk_size;
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 	}
 
 	root->fs_info->system_allocs = 0;
-	btrfs_commit_transaction(trans, root);
+	ret = btrfs_commit_transaction(trans, root);
 
 err:
 	return ret;
@@ -138,13 +143,15 @@ static int create_data_block_groups(struct btrfs_trans_handle *trans,
 			error("no space to allocate data chunk");
 			goto err;
 		}
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 		ret = btrfs_make_block_group(trans, root, 0,
 					     BTRFS_BLOCK_GROUP_DATA,
 					     BTRFS_FIRST_CHUNK_TREE_OBJECTID,
 					     chunk_start, chunk_size);
 		allocation->data += chunk_size;
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 	}
 
 err:
@@ -226,23 +233,29 @@ static int create_one_raid_group(struct btrfs_trans_handle *trans,
 		error("not enough free space to allocate chunk");
 		exit(1);
 	}
-	BUG_ON(ret);
+	if (ret)
+		return ret;
+
 	ret = btrfs_make_block_group(trans, root->fs_info->extent_root, 0,
 				     type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
 				     chunk_start, chunk_size);
-	if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == BTRFS_BLOCK_GROUP_DATA)
+
+	type &= BTRFS_BLOCK_GROUP_TYPE_MASK;
+	if (type == BTRFS_BLOCK_GROUP_DATA) {
 		allocation->data += chunk_size;
-	else if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == BTRFS_BLOCK_GROUP_METADATA)
+	} else if (type == BTRFS_BLOCK_GROUP_METADATA) {
 		allocation->metadata += chunk_size;
-	else if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == BTRFS_BLOCK_GROUP_SYSTEM)
+	} else if (type == BTRFS_BLOCK_GROUP_SYSTEM) {
 		allocation->system += chunk_size;
-	else if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) ==
-			(BTRFS_BLOCK_GROUP_METADATA|BTRFS_BLOCK_GROUP_DATA))
+	} else if (type ==
+			(BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA)) {
 		allocation->mixed += chunk_size;
-	else
-		BUG_ON(1);
+	} else {
+		error("unrecognized profile type: 0x%llx",
+				(unsigned long long)type);
+		ret = -EINVAL;
+	}
 
-	BUG_ON(ret);
 	return ret;
 }
 
@@ -259,21 +272,24 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
 		ret = create_one_raid_group(trans, root,
 					    BTRFS_BLOCK_GROUP_SYSTEM |
 					    metadata_profile, allocation);
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 
 		if (mixed)
 			meta_flags |= BTRFS_BLOCK_GROUP_DATA;
 
 		ret = create_one_raid_group(trans, root, meta_flags |
 					    metadata_profile, allocation);
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 
 	}
 	if (!mixed && data_profile) {
 		ret = create_one_raid_group(trans, root,
 					    BTRFS_BLOCK_GROUP_DATA |
 					    data_profile, allocation);
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 	}
 	recow_roots(trans, root);
 
@@ -290,7 +306,8 @@ static int create_data_reloc_tree(struct btrfs_trans_handle *trans,
 	int ret;
 
 	ret = btrfs_copy_root(trans, root, root->node, &tmp, objectid);
-	BUG_ON(ret);
+	if (ret)
+		return ret;
 
 	memcpy(&root_item, &root->root_item, sizeof(root_item));
 	btrfs_set_root_bytenr(&root_item, tmp->start);
@@ -303,8 +320,8 @@ static int create_data_reloc_tree(struct btrfs_trans_handle *trans,
 	location.offset = 0;
 	ret = btrfs_insert_root(trans, root->fs_info->tree_root,
 				&location, &root_item);
-	BUG_ON(ret);
-	return 0;
+
+	return ret;
 }
 
 static void print_usage(int ret)
@@ -968,12 +985,14 @@ static int create_chunks(struct btrfs_trans_handle *trans,
 	for (i = 0; i < num_of_meta_chunks; i++) {
 		ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
 					&chunk_start, &chunk_size, meta_type);
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 		ret = btrfs_make_block_group(trans, root->fs_info->extent_root, 0,
 					     meta_type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
 					     chunk_start, chunk_size);
 		allocation->metadata += chunk_size;
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 		set_extent_dirty(&root->fs_info->free_space_cache,
 				 chunk_start, chunk_start + chunk_size - 1, 0);
 	}
@@ -983,12 +1002,14 @@ static int create_chunks(struct btrfs_trans_handle *trans,
 
 	ret = btrfs_alloc_data_chunk(trans, root->fs_info->extent_root,
 				     &chunk_start, size_of_data, data_type, 0);
-	BUG_ON(ret);
+	if (ret)
+		return ret;
 	ret = btrfs_make_block_group(trans, root->fs_info->extent_root, 0,
 				     data_type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
 				     chunk_start, size_of_data);
 	allocation->data += size_of_data;
-	BUG_ON(ret);
+	if (ret)
+		return ret;
 	set_extent_dirty(&root->fs_info->free_space_cache,
 			 chunk_start, chunk_start + size_of_data - 1, 0);
 	return ret;
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 07/13] btrfs-progs: mkfs: improve error handling in main()
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (5 preceding siblings ...)
  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 ` David Sterba
  2016-08-23 10:25 ` [PATCH 08/13] btrfs-progs: mkfs: improve error handling in recow_roots David Sterba
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 49 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 14 deletions(-)

diff --git a/mkfs.c b/mkfs.c
index b2baf47bb595..94b349f157ca 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1805,7 +1805,10 @@ int main(int argc, char **argv)
 
 		ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count,
 					sectorsize, sectorsize, sectorsize);
-		BUG_ON(ret);
+		if (ret) {
+			error("unable to add %s to filesystem: %d", file, ret);
+			goto out;
+		}
 		if (verbose >= 2) {
 			struct btrfs_device *device;
 
@@ -1820,11 +1823,17 @@ int main(int argc, char **argv)
 	if (!source_dir_set) {
 		ret = create_raid_groups(trans, root, data_profile,
 				 metadata_profile, mixed, &allocation);
-		BUG_ON(ret);
+		if (ret) {
+			error("unable to create raid groups: %d", ret);
+			goto out;
+		}
 	}
 
 	ret = create_data_reloc_tree(trans, root);
-	BUG_ON(ret);
+	if (ret) {
+		error("unable to create data reloc tree: %d", ret);
+		goto out;
+	}
 
 	btrfs_commit_transaction(trans, root);
 
@@ -1833,11 +1842,21 @@ int main(int argc, char **argv)
 		ret = create_chunks(trans, root,
 				    num_of_meta_chunks, size_of_data,
 				    &allocation);
-		BUG_ON(ret);
-		btrfs_commit_transaction(trans, root);
+		if (ret) {
+			error("unable to create chunks: %d", ret);
+			goto out;
+		}
+		ret = btrfs_commit_transaction(trans, root);
+		if (ret) {
+			error("transaction commit failed: %d", ret);
+			goto out;
+		}
 
 		ret = make_image(source_dir, root, fd);
-		BUG_ON(ret);
+		if (ret) {
+			error("error wihle filling filesystem: %d", ret);
+			goto out;
+		}
 	}
 	ret = cleanup_temp_chunks(root->fs_info, &allocation, data_profile,
 				  metadata_profile, metadata_profile);
@@ -1886,17 +1905,19 @@ int main(int argc, char **argv)
 	root->fs_info->finalize_on_close = 1;
 out:
 	ret = close_ctree(root);
-	BUG_ON(ret);
 
-	optind = saved_optind;
-	dev_cnt = argc - optind;
-	while (dev_cnt-- > 0) {
-		file = argv[optind++];
-		if (is_block_device(file) == 1)
-			btrfs_register_one_device(file);
+	if (!ret) {
+		optind = saved_optind;
+		dev_cnt = argc - optind;
+		while (dev_cnt-- > 0) {
+			file = argv[optind++];
+			if (is_block_device(file) == 1)
+				btrfs_register_one_device(file);
+		}
 	}
 
 	btrfs_close_all_devices();
 	free(label);
-	return 0;
+
+	return !!ret;
 }
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 08/13] btrfs-progs: mkfs: improve error handling in recow_roots
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (6 preceding siblings ...)
  2016-08-23 10:25 ` [PATCH 07/13] btrfs-progs: mkfs: improve error handling in main() David Sterba
@ 2016-08-23 10:25 ` David Sterba
  2016-08-23 10:25 ` [PATCH 09/13] btrfs-progs: document all btrfs_open_ctree_flags David Sterba
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Return and handle errors in the callchain.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 42 ++++++++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/mkfs.c b/mkfs.c
index 94b349f157ca..3f0a3322cc76 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -190,32 +190,50 @@ static int make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *ro
 	return ret;
 }
 
-static void __recow_root(struct btrfs_trans_handle *trans,
+static int __recow_root(struct btrfs_trans_handle *trans,
 			 struct btrfs_root *root)
 {
-	int ret;
 	struct extent_buffer *tmp;
+	int ret;
 
 	if (trans->transid != btrfs_root_generation(&root->root_item)) {
 		extent_buffer_get(root->node);
 		ret = __btrfs_cow_block(trans, root, root->node,
 					NULL, 0, &tmp, 0, 0);
-		BUG_ON(ret);
+		if (ret)
+			return ret;
 		free_extent_buffer(tmp);
 	}
+
+	return 0;
 }
 
-static void recow_roots(struct btrfs_trans_handle *trans,
+static int recow_roots(struct btrfs_trans_handle *trans,
 		       struct btrfs_root *root)
 {
 	struct btrfs_fs_info *info = root->fs_info;
+	int ret;
 
-	__recow_root(trans, info->fs_root);
-	__recow_root(trans, info->tree_root);
-	__recow_root(trans, info->extent_root);
-	__recow_root(trans, info->chunk_root);
-	__recow_root(trans, info->dev_root);
-	__recow_root(trans, info->csum_root);
+	ret = __recow_root(trans, info->fs_root);
+	if (ret)
+		return ret;
+	ret = __recow_root(trans, info->tree_root);
+	if (ret)
+		return ret;
+	ret = __recow_root(trans, info->extent_root);
+	if (ret)
+		return ret;
+	ret = __recow_root(trans, info->chunk_root);
+	if (ret)
+		return ret;
+	ret = __recow_root(trans, info->dev_root);
+	if (ret)
+		return ret;
+	ret = __recow_root(trans, info->csum_root);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 
 static int create_one_raid_group(struct btrfs_trans_handle *trans,
@@ -291,9 +309,9 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
 		if (ret)
 			return ret;
 	}
-	recow_roots(trans, root);
+	ret = recow_roots(trans, root);
 
-	return 0;
+	return ret;
 }
 
 static int create_data_reloc_tree(struct btrfs_trans_handle *trans,
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 09/13] btrfs-progs: document all btrfs_open_ctree_flags
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (7 preceding siblings ...)
  2016-08-23 10:25 ` [PATCH 08/13] btrfs-progs: mkfs: improve error handling in recow_roots David Sterba
@ 2016-08-23 10:25 ` David Sterba
  2016-08-23 10:25 ` [PATCH 10/13] btrfs-progs: mkfs: switch BUG_ON to error handling in traverse_directory David Sterba
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Document and add unsigned type to the values.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 disk-io.h | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/disk-io.h b/disk-io.h
index a73dede1e8d0..c404d3f4fdfe 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -29,21 +29,29 @@
 #define BTRFS_SUPER_MIRROR_SHIFT 12
 
 enum btrfs_open_ctree_flags {
-	OPEN_CTREE_WRITES		= (1 << 0),
-	OPEN_CTREE_PARTIAL		= (1 << 1),
-	OPEN_CTREE_BACKUP_ROOT		= (1 << 2),
-	OPEN_CTREE_RECOVER_SUPER	= (1 << 3),
-	OPEN_CTREE_RESTORE		= (1 << 4),
-	OPEN_CTREE_NO_BLOCK_GROUPS	= (1 << 5),
-	OPEN_CTREE_EXCLUSIVE		= (1 << 6),
-	OPEN_CTREE_NO_DEVICES		= (1 << 7),
+	/* Open filesystem for writes */
+	OPEN_CTREE_WRITES		= (1U << 0),
+	/* Allow to open filesystem with some broken tree roots (eg log root) */
+	OPEN_CTREE_PARTIAL		= (1U << 1),
+	/* If primary root pinters are invalid, try backup copies */
+	OPEN_CTREE_BACKUP_ROOT		= (1U << 2),
+	/* Allow reading all superblock sopies if the primary is damaged */
+	OPEN_CTREE_RECOVER_SUPER	= (1U << 3),
+	/* Restoring filesystem image */
+	OPEN_CTREE_RESTORE		= (1U << 4),
+	/* Do not read block groups (extent tree) */
+	OPEN_CTREE_NO_BLOCK_GROUPS	= (1U << 5),
+	/* Open all devices in O_EXCL mode */
+	OPEN_CTREE_EXCLUSIVE		= (1U << 6),
+	/* Do not scan devices */
+	OPEN_CTREE_NO_DEVICES		= (1U << 7),
 	/*
 	 * Don't print error messages if bytenr or checksums do not match in
 	 * tree block headers. Turn on by OPEN_CTREE_SUPPRESS_ERROR
 	 */
-	OPEN_CTREE_SUPPRESS_CHECK_BLOCK_ERRORS	= (1 << 8),
-	/* Return chunk root */
-	__OPEN_CTREE_RETURN_CHUNK_ROOT	= (1 << 9),
+	OPEN_CTREE_SUPPRESS_CHECK_BLOCK_ERRORS	= (1U << 8),
+	/* Return the chunk root */
+	__OPEN_CTREE_RETURN_CHUNK_ROOT	= (1U << 9),
 	OPEN_CTREE_CHUNK_ROOT_ONLY	= OPEN_CTREE_PARTIAL +
 					  OPEN_CTREE_SUPPRESS_CHECK_BLOCK_ERRORS +
 					  __OPEN_CTREE_RETURN_CHUNK_ROOT,
@@ -53,18 +61,19 @@ enum btrfs_open_ctree_flags {
 	 * Like split PARTIAL into SKIP_CSUM/SKIP_EXTENT
 	 */
 
-	OPEN_CTREE_IGNORE_FSID_MISMATCH	= (1 << 10),
+	/* Ignore UUID mismatches */
+	OPEN_CTREE_IGNORE_FSID_MISMATCH	= (1U << 10),
 
 	/*
-	 * Allow open_ctree_fs_info() to return a incomplete fs_info with
+	 * Allow open_ctree_fs_info() to return an incomplete fs_info with
 	 * system chunks from super block only.
-	 * It's useful for chunk corruption case.
+	 * It's useful when chunks are corrupted.
 	 * Makes no sense for open_ctree variants returning btrfs_root.
 	 */
-	OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR = (1 << 11),
+	OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR = (1U << 11),
 
 	/* Allow to open a partially created filesystem */
-	OPEN_CTREE_FS_PARTIAL = (1 << 12),
+	OPEN_CTREE_FS_PARTIAL = (1U << 12),
 };
 
 /*
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 10/13] btrfs-progs: mkfs: switch BUG_ON to error handling in traverse_directory
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (8 preceding siblings ...)
  2016-08-23 10:25 ` [PATCH 09/13] btrfs-progs: document all btrfs_open_ctree_flags David Sterba
@ 2016-08-23 10:25 ` David Sterba
  2016-08-23 10:25 ` [PATCH 11/13] btrfs-progs: mkfs: handle and report transaction commit failures David Sterba
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/mkfs.c b/mkfs.c
index 3f0a3322cc76..c28a8bb7e983 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -910,7 +910,12 @@ static int traverse_directory(struct btrfs_trans_handle *trans,
 					      parent_inum, dir_index_cnt,
 					      &cur_inode);
 			if (ret == -EEXIST) {
-				BUG_ON(st.st_nlink <= 1);
+				if (st.st_nlink <= 1) {
+					error(
+			"item %s already exists but has wrong st_nlink %ld <= 1",
+						cur_file->d_name, st.st_nlink);
+					goto fail;
+				}
 				continue;
 			}
 			if (ret) {
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 11/13] btrfs-progs: mkfs: handle and report transaction commit failures
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (9 preceding siblings ...)
  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 ` 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
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/mkfs.c b/mkfs.c
index c28a8bb7e983..f063323903dc 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1063,7 +1063,11 @@ static int make_image(char *source_dir, struct btrfs_root *root, int out_fd)
 		error("unable to traverse directory %s: %d", source_dir, ret);
 		goto fail;
 	}
-	btrfs_commit_transaction(trans, root);
+	ret = btrfs_commit_transaction(trans, root);
+	if (ret) {
+		error("transaction commit failed: %d", ret);
+		goto out;
+	}
 
 	if (verbose)
 		printf("Making image is completed.\n");
@@ -1784,7 +1788,11 @@ int main(int argc, char **argv)
 		exit(1);
 	}
 
-	btrfs_commit_transaction(trans, root);
+	ret = btrfs_commit_transaction(trans, root);
+	if (ret) {
+		error("unable to commit transaction: %d", ret);
+		goto out;
+	}
 
 	trans = btrfs_start_transaction(root, 1);
 	if (!trans) {
@@ -1858,7 +1866,11 @@ int main(int argc, char **argv)
 		goto out;
 	}
 
-	btrfs_commit_transaction(trans, root);
+	ret = btrfs_commit_transaction(trans, root);
+	if (ret) {
+		error("unable to commit transaction: %d", ret);
+		goto out;
+	}
 
 	if (source_dir_set) {
 		trans = btrfs_start_transaction(root, 1);
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 12/13] btrfs-progs: mkfs: help and usage now to to stdout
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (10 preceding siblings ...)
  2016-08-23 10:25 ` [PATCH 11/13] btrfs-progs: mkfs: handle and report transaction commit failures David Sterba
@ 2016-08-23 10:25 ` David Sterba
  2016-08-23 10:25 ` [PATCH 13/13] btrfs-progs: mkfs: clean up make_image David Sterba
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/mkfs.c b/mkfs.c
index f063323903dc..ef0b099a58d7 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -344,31 +344,31 @@ static int create_data_reloc_tree(struct btrfs_trans_handle *trans,
 
 static void print_usage(int ret)
 {
-	fprintf(stderr, "usage: mkfs.btrfs [options] dev [ dev ... ]\n");
-	fprintf(stderr, "options:\n");
-	fprintf(stderr, "\t-A|--alloc-start START  the offset to start the FS\n");
-	fprintf(stderr, "\t-b|--byte-count SIZE    total number of bytes in the FS\n");
-	fprintf(stderr, "\t-d|--data PROFILE       data profile, raid0, raid1, raid5, raid6, raid10, dup or single\n");
-	fprintf(stderr, "\t-f|--force              force overwrite of existing filesystem\n");
-	fprintf(stderr, "\t-l|--leafsize SIZE      deprecated, alias for nodesize\n");
-	fprintf(stderr, "\t-L|--label LABEL        set a label\n");
-	fprintf(stderr, "\t-m|--metadata PROFILE   metadata profile, values like data profile\n");
-	fprintf(stderr, "\t-M|--mixed              mix metadata and data together\n");
-	fprintf(stderr, "\t-n|--nodesize SIZE      size of btree nodes\n");
-	fprintf(stderr, "\t-s|--sectorsize SIZE    min block allocation (may not mountable by current kernel)\n");
-	fprintf(stderr, "\t-r|--rootdir DIR        the source directory\n");
-	fprintf(stderr, "\t-K|--nodiscard          do not perform whole device TRIM\n");
-	fprintf(stderr, "\t-O|--features LIST      comma separated list of filesystem features, use '-O list-all' to list features\n");
-	fprintf(stderr, "\t-U|--uuid UUID          specify the filesystem UUID\n");
-	fprintf(stderr, "\t-q|--quiet              no messages except errors\n");
-	fprintf(stderr, "\t-V|--version            print the mkfs.btrfs version and exit\n");
+	printf("usage: mkfs.btrfs [options] dev [ dev ... ]\n");
+	printf("options:\n");
+	printf("\t-A|--alloc-start START  the offset to start the FS\n");
+	printf("\t-b|--byte-count SIZE    total number of bytes in the FS\n");
+	printf("\t-d|--data PROFILE       data profile, raid0, raid1, raid5, raid6, raid10, dup or single\n");
+	printf("\t-f|--force              force overwrite of existing filesystem\n");
+	printf("\t-l|--leafsize SIZE      deprecated, alias for nodesize\n");
+	printf("\t-L|--label LABEL        set a label\n");
+	printf("\t-m|--metadata PROFILE   metadata profile, values like data profile\n");
+	printf("\t-M|--mixed              mix metadata and data together\n");
+	printf("\t-n|--nodesize SIZE      size of btree nodes\n");
+	printf("\t-s|--sectorsize SIZE    min block allocation (may not mountable by current kernel)\n");
+	printf("\t-r|--rootdir DIR        the source directory\n");
+	printf("\t-K|--nodiscard          do not perform whole device TRIM\n");
+	printf("\t-O|--features LIST      comma separated list of filesystem features, use '-O list-all' to list features\n");
+	printf("\t-U|--uuid UUID          specify the filesystem UUID\n");
+	printf("\t-q|--quiet              no messages except errors\n");
+	printf("\t-V|--version            print the mkfs.btrfs version and exit\n");
 	exit(ret);
 }
 
 static void print_version(void) __attribute__((noreturn));
 static void print_version(void)
 {
-	fprintf(stderr, "mkfs.btrfs, part of %s\n", PACKAGE_STRING);
+	printf("mkfs.btrfs, part of %s\n", PACKAGE_STRING);
 	exit(0);
 }
 
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 13/13] btrfs-progs: mkfs: clean up make_image
  2016-08-23 10:25 [PATCH 00/13] Btrfs-progs: partial mkfs/convert, error handling, cleanups David Sterba
                   ` (11 preceding siblings ...)
  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 ` David Sterba
  12 siblings, 0 replies; 16+ messages in thread
From: David Sterba @ 2016-08-23 10:25 UTC (permalink / raw)
  To: linux-btrfs; +Cc: David Sterba

The exact errors are printed, the removed message does not seem to be
necessary. Return proper errors.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 mkfs.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/mkfs.c b/mkfs.c
index ef0b099a58d7..2aa1d5d31523 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1042,16 +1042,14 @@ static int make_image(char *source_dir, struct btrfs_root *root, int out_fd)
 {
 	int ret;
 	struct btrfs_trans_handle *trans;
-
 	struct stat root_st;
-
 	struct directory_name_entry dir_head;
-
 	struct directory_name_entry *dir_entry = NULL;
 
 	ret = lstat(source_dir, &root_st);
 	if (ret) {
 		error("unable to lstat %s: %s", source_dir, strerror(errno));
+		ret = -errno;
 		goto out;
 	}
 
@@ -1080,8 +1078,7 @@ static int make_image(char *source_dir, struct btrfs_root *root, int out_fd)
 		free(dir_entry);
 	}
 out:
-	fprintf(stderr, "Making image is aborted.\n");
-	return -1;
+	return ret;
 }
 
 /*
-- 
2.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/13] btrfs-progs: pass OPEN_CTREE flags as unsigned
  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
  0 siblings, 0 replies; 16+ messages in thread
From: Anand Jain @ 2016-08-24 10:24 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



All patches looks good. nice cleanups.


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

Thanks.


On 08/23/2016 06:25 PM, David Sterba wrote:
> As we're passing a set of flags, the enum type is not appropriate.
>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>  btrfstune.c  |  2 +-
>  cmds-check.c |  2 +-
>  disk-io.c    | 12 ++++++------
>  disk-io.h    |  8 ++++----
>  4 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/btrfstune.c b/btrfstune.c
> index ac559fb9e3de..93b25e8cece8 100644
> --- a/btrfstune.c
> +++ b/btrfstune.c
> @@ -389,7 +389,7 @@ static void print_usage(void)
>  int main(int argc, char *argv[])
>  {
>  	struct btrfs_root *root;
> -	enum btrfs_open_ctree_flags ctree_flags = OPEN_CTREE_WRITES;
> +	unsigned ctree_flags = OPEN_CTREE_WRITES;
>  	int success = 0;
>  	int total = 0;
>  	int seeding_flag = 0;
> diff --git a/cmds-check.c b/cmds-check.c
> index fc15ce98f4bb..0ddfd24a4d8e 100644
> --- a/cmds-check.c
> +++ b/cmds-check.c
> @@ -11178,7 +11178,7 @@ int cmd_check(int argc, char **argv)
>  	int readonly = 0;
>  	int qgroup_report = 0;
>  	int qgroups_repaired = 0;
> -	enum btrfs_open_ctree_flags ctree_flags = OPEN_CTREE_EXCLUSIVE;
> +	unsigned ctree_flags = OPEN_CTREE_EXCLUSIVE;
>
>  	while(1) {
>  		int c;
> diff --git a/disk-io.c b/disk-io.c
> index 3647ecca7e63..279e38b74c39 100644
> --- a/disk-io.c
> +++ b/disk-io.c
> @@ -932,7 +932,7 @@ static int find_best_backup_root(struct btrfs_super_block *super)
>  }
>
>  static int setup_root_or_create_block(struct btrfs_fs_info *fs_info,
> -				      enum btrfs_open_ctree_flags flags,
> +				      unsigned flags,
>  				      struct btrfs_root *info_root,
>  				      u64 objectid, char *str)
>  {
> @@ -961,7 +961,7 @@ static int setup_root_or_create_block(struct btrfs_fs_info *fs_info,
>  }
>
>  int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
> -			  enum btrfs_open_ctree_flags flags)
> +			  unsigned flags)
>  {
>  	struct btrfs_super_block *sb = fs_info->super_copy;
>  	struct btrfs_root *root;
> @@ -1217,7 +1217,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
>  					     u64 sb_bytenr,
>  					     u64 root_tree_bytenr,
>  					     u64 chunk_root_bytenr,
> -					     enum btrfs_open_ctree_flags flags)
> +					     unsigned flags)
>  {
>  	struct btrfs_fs_info *fs_info;
>  	struct btrfs_super_block *disk_super;
> @@ -1323,7 +1323,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
>  struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
>  					 u64 sb_bytenr, u64 root_tree_bytenr,
>  					 u64 chunk_root_bytenr,
> -					 enum btrfs_open_ctree_flags flags)
> +					 unsigned flags)
>  {
>  	int fp;
>  	int ret;
> @@ -1356,7 +1356,7 @@ struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
>  }
>
>  struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
> -			      enum btrfs_open_ctree_flags flags)
> +			      unsigned flags)
>  {
>  	struct btrfs_fs_info *info;
>
> @@ -1371,7 +1371,7 @@ struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
>  }
>
>  struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
> -				 enum btrfs_open_ctree_flags flags)
> +				 unsigned flags)
>  {
>  	struct btrfs_fs_info *info;
>
> diff --git a/disk-io.h b/disk-io.h
> index d6fb9822614f..9ebb2366b933 100644
> --- a/disk-io.h
> +++ b/disk-io.h
> @@ -103,7 +103,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info);
>  struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr);
>  int btrfs_check_fs_compatibility(struct btrfs_super_block *sb, int writable);
>  int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
> -			  enum btrfs_open_ctree_flags flags);
> +			  unsigned flags);
>  void btrfs_release_all_roots(struct btrfs_fs_info *fs_info);
>  void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info);
>  int btrfs_scan_fs_devices(int fd, const char *path,
> @@ -113,13 +113,13 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
>  			  u64 chunk_root_bytenr);
>
>  struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
> -			      enum btrfs_open_ctree_flags flags);
> +			      unsigned flags);
>  struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
> -				 enum btrfs_open_ctree_flags flags);
> +				 unsigned flags);
>  struct btrfs_fs_info *open_ctree_fs_info(const char *filename,
>  					 u64 sb_bytenr, u64 root_tree_bytenr,
>  					 u64 chunk_root_bytenr,
> -					 enum btrfs_open_ctree_flags flags);
> +					 unsigned flags);
>  int close_ctree_fs_info(struct btrfs_fs_info *fs_info);
>  static inline int close_ctree(struct btrfs_root *root)
>  {
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 05/13] btrfs-progs: two staged filesystem creation
  2016-08-23 10:25 ` [PATCH 05/13] btrfs-progs: two staged filesystem creation David Sterba
@ 2016-08-24 10:27   ` Anand Jain
  0 siblings, 0 replies; 16+ messages in thread
From: Anand Jain @ 2016-08-24 10:27 UTC (permalink / raw)
  To: David Sterba, linux-btrfs



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]);
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-08-24 10:27 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.