aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAnand Jain <anand.jain@oracle.com>2014-04-06 00:59:07 -0400
committerChris Mason <clm@fb.com>2014-06-09 20:20:41 -0400
commit4d90d28b1c5c5ab6292c0888dc1ebdfc3023f877 (patch)
treedde05db2c69de9bce804b7f5c650aa8b2094c9e8 /fs
parent27cdeb7096b86f05ad018a24cdb63acdf0850a5d (diff)
btrfs: btrfs_rm_device() should zero mirror SB as well
This fix will ensure all SB copies on the disk is zeroed when the disk is intentionally removed. This helps to better manage disks in the user land. This version of patch also merges the Zach patch as below. btrfs: don't double brelse on device rm Signed-off-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: Zach Brown <zab@redhat.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/volumes.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 8113f4567084..ee71622088f9 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1710,12 +1710,43 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1710 * remove it from the devices list and zero out the old super 1710 * remove it from the devices list and zero out the old super
1711 */ 1711 */
1712 if (clear_super && disk_super) { 1712 if (clear_super && disk_super) {
1713 u64 bytenr;
1714 int i;
1715
1713 /* make sure this device isn't detected as part of 1716 /* make sure this device isn't detected as part of
1714 * the FS anymore 1717 * the FS anymore
1715 */ 1718 */
1716 memset(&disk_super->magic, 0, sizeof(disk_super->magic)); 1719 memset(&disk_super->magic, 0, sizeof(disk_super->magic));
1717 set_buffer_dirty(bh); 1720 set_buffer_dirty(bh);
1718 sync_dirty_buffer(bh); 1721 sync_dirty_buffer(bh);
1722
1723 /* clear the mirror copies of super block on the disk
1724 * being removed, 0th copy is been taken care above and
1725 * the below would take of the rest
1726 */
1727 for (i = 1; i < BTRFS_SUPER_MIRROR_MAX; i++) {
1728 bytenr = btrfs_sb_offset(i);
1729 if (bytenr + BTRFS_SUPER_INFO_SIZE >=
1730 i_size_read(bdev->bd_inode))
1731 break;
1732
1733 brelse(bh);
1734 bh = __bread(bdev, bytenr / 4096,
1735 BTRFS_SUPER_INFO_SIZE);
1736 if (!bh)
1737 continue;
1738
1739 disk_super = (struct btrfs_super_block *)bh->b_data;
1740
1741 if (btrfs_super_bytenr(disk_super) != bytenr ||
1742 btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
1743 continue;
1744 }
1745 memset(&disk_super->magic, 0,
1746 sizeof(disk_super->magic));
1747 set_buffer_dirty(bh);
1748 sync_dirty_buffer(bh);
1749 }
1719 } 1750 }
1720 1751
1721 ret = 0; 1752 ret = 0;