There is a very less chance that all the copies of SB
on the disk is zeroed unintentionally. unless device
is removed, so this fix will ensure all copies on the
disk is zeroed when the disk is intentionally removed.
reproducer:
-------------------
btrfs dev del /dev/sdc /btrfs
echo $?
0
umount /btrfs
btrfs fi show
Label: none uuid: e7aae9f0-1aa8-41f5-8fb6-d4d8f80cdb2c
Total devices 1 FS bytes used 28.00KiB
devid 1 size 2.00GiB used 20.00MiB path /dev/sdb
./btrfs-select-super -s 1 /dev/sdc
using SB copy 1, bytenr 67108864
btrfs fi show
Label: none uuid: e7aae9f0-1aa8-41f5-8fb6-d4d8f80cdb2c
Total devices 1 FS bytes used 28.00KiB
devid 2 size 2.00GiB used 0.00 path /dev/sdc <-- WRONG
devid 1 size 2.00GiB used 20.00MiB path /dev/sdb
mount /dev/sdc /btrfs
btrfs fi show --kernel
Label: none uuid: e7aae9f0-1aa8-41f5-8fb6-d4d8f80cdb2c mounted: /btrfs
Group profile: metadata: single data: single
Total devices 1 FS bytes used 28.00KiB
devid 1 size 2.00GiB used 20.00MiB path /dev/sdb
---------------------
Signed-off-by: Anand Jain <anand.jain@xxxxxxxxxx>
---
fs/btrfs/volumes.c | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 557a743..090f57c 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1641,12 +1641,42 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
* remove it from the devices list and zero out the old super
*/
if (clear_super && disk_super) {
+ u64 bytenr;
+ int i;
+
/* make sure this device isn't detected as part of
* the FS anymore
*/
memset(&disk_super->magic, 0, sizeof(disk_super->magic));
set_buffer_dirty(bh);
sync_dirty_buffer(bh);
+
+ /* clear the mirror copies of super block on the disk
+ * being removed, 0th copy is been taken care above and
+ * the below would take of the rest
+ */
+ for (i = 1; i < BTRFS_SUPER_MIRROR_MAX; i++) {
+ brelse(bh);
+ bytenr = btrfs_sb_offset(i);
+ if (bytenr + BTRFS_SUPER_INFO_SIZE >=
+ i_size_read(bdev->bd_inode))
+ break;
+ bh = __bread(bdev, bytenr / 4096,
+ BTRFS_SUPER_INFO_SIZE);
+ if (!bh)
+ continue;
+
+ disk_super = (struct btrfs_super_block *)bh->b_data;
+
+ if (btrfs_super_bytenr(disk_super) != bytenr ||
+ btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
+ continue;
+ }
+ memset(&disk_super->magic, 0,
+ sizeof(disk_super->magic));
+ set_buffer_dirty(bh);
+ sync_dirty_buffer(bh);
+ }
}
ret = 0;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html