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 <type> 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 <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
This commit is contained in:
Anand Jain 2014-10-02 07:22:09 +08:00 committed by David Sterba
parent 2c0e02a568
commit d0b24918f6
1 changed files with 38 additions and 0 deletions

38
utils.c
View File

@ -678,6 +678,42 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
return 0; 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, int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
u64 max_block_count, int *mixed, int discard) 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; return 1;
} }
btrfs_wipe_existing_sb(fd);
*block_count_ret = block_count; *block_count_ret = block_count;
return 0; return 0;
} }