path: root/volumes.c
diff options
authorGui Hecheng <>2014-10-06 18:17:49 +0800
committerDavid Sterba <>2014-10-10 10:38:38 +0200
commitcb37bf83cc583dfe1e22344049a649b363228509 (patch)
tree6bdd250aa0fcc4261a84352a9eaee99b6c080b61 /volumes.c
parent0cf497719cf8d2c6f7967a386a7b54b0119fd1b4 (diff)
btrfs-progs: fix BUG_ON when all devices under seed fs are missing
Steps to reproduce: # mkfs.btrfs -f /dev/sda[1-2] # btrfstune -S 1 /dev/sda1 # mount /dev/sda /mnt # btrfs dev add /dev/sda3 /mnt # umount /mnt # mkfs.ext4 /dev/sda1 // kill seed dev # mkfs.ext4 /dev/sda2 // kill seed dev # btrfs-debug-tree /dev/sda3 <== BUG_ON Output msg: volumes.c:1824: btrfs_read_chunk_tree: Assertion `ret` failed. btrfs-debug-tree[0x41cb36] btrfs-debug-tree(btrfs_read_chunk_tree+0x3ca) btrfs-debug-tree(btrfs_setup_chunk_tree_and_device_map btrfs-debug-tree[0x40f695] btrfs-debug-tree(open_ctree_fs_info+0x86) btrfs-debug-tree(main+0x12d) /lib64/ btrfs-debug-tree[0x4062e9] This BUG_ON complains about a failed @read_one_dev() call when @open_seed_devices() failed to find the seed @fs_devices object for a dev_item in chunk tree. In this case, just insert a "shadow" @fs_devices with the fsid in dev_item shall make no harm since no other tools will try to make use of the stuff that the "shadow" @fs_devices possesses after its creation. After apply this commit, btrfs-debug-tree will report unable to open the device. Signed-off-by: Gui Hecheng <> Signed-off-by: David Sterba <>
Diffstat (limited to 'volumes.c')
1 files changed, 9 insertions, 2 deletions
diff --git a/volumes.c b/volumes.c
index 009ce785..b47bce6b 100644
--- a/volumes.c
+++ b/volumes.c
@@ -1672,8 +1672,15 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid)
fs_devices = find_fsid(fsid);
if (!fs_devices) {
- ret = -ENOENT;
- goto out;
+ /* missing all seed devices */
+ fs_devices = kzalloc(sizeof(*fs_devices), GFP_NOFS);
+ if (!fs_devices) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ INIT_LIST_HEAD(&fs_devices->devices);
+ list_add(&fs_devices->list, &fs_uuids);
+ memcpy(fs_devices->fsid, fsid, BTRFS_FSID_SIZE);
ret = btrfs_open_devices(fs_devices, O_RDONLY);