From d0b24918f6a593969ccbdcf861c142ba2ccc67b7 Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Thu, 2 Oct 2014 07:22:09 +0800 Subject: [PATCH] btrfs-progs: force overwrite should wipe stale SB (I am unable to reproduce the issue, tried to go back with progs versions but still the same. So as of now this code remains untested, suggest to wait till we have a reproducible test case). Here is a test case which says it all.. mkfs.xfs -f $DEV mkfs.btrfs -f $DEV mount $DEV $MNT mount: /dev/vdiskc: more filesystems detected. This should not happen, use -t to explicitly specify the filesystem type or use wipefs(8) to clean up the device. mount: you must specify the filesystem type with this patch btrfs_prepare_device() also wipes old FS if any, btrfs_prepare_device() is called after we have verified that user has provided -f option. Signed-off-by: Anand Jain Signed-off-by: David Sterba --- utils.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/utils.c b/utils.c index 32a795e4..a7277281 100644 --- a/utils.c +++ b/utils.c @@ -678,6 +678,42 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, return 0; } +static void btrfs_wipe_existing_sb(int fd) +{ + const char *off = NULL; + size_t len = 0; + loff_t offset; + char buf[BUFSIZ]; + int rc = 0; + blkid_probe pr = NULL; + + pr = blkid_new_probe(); + if (!pr) + return; + + if (blkid_probe_set_device(pr, fd, 0, 0)) + goto out; + + rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL); + if (!rc) + rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len); + + if (rc || len == 0 || off == NULL) + goto out; + + offset = strtoll(off, NULL, 10); + if (len > sizeof(buf)) + len = sizeof(buf); + + memset(buf, 0, len); + rc = pwrite(fd, buf, len, offset); + fsync(fd); + +out: + blkid_free_probe(pr); + return; +} + int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, u64 max_block_count, int *mixed, int discard) { @@ -729,6 +765,8 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, return 1; } + btrfs_wipe_existing_sb(fd); + *block_count_ret = block_count; return 0; }