btrfs-progs: handle errors in btrfs_wipe_existing_sb

Failure during superblock wiping is not always a hard error as we're
going to overwrite it anyway but it may catch some errors earlier. The
error message is not very descriptive though, because we don't get back
much information from blkid.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2015-09-01 16:00:12 +02:00
parent c4123e1848
commit 17e1e872d4

39
utils.c
View file

@ -798,40 +798,52 @@ err_nomem:
return -ENOMEM;
}
static void btrfs_wipe_existing_sb(int fd)
static int btrfs_wipe_existing_sb(int fd)
{
const char *off = NULL;
size_t len = 0;
loff_t offset;
char buf[BUFSIZ];
int rc = 0;
int ret = 0;
blkid_probe pr = NULL;
pr = blkid_new_probe();
if (!pr)
return;
return -1;
if (blkid_probe_set_device(pr, fd, 0, 0))
if (blkid_probe_set_device(pr, fd, 0, 0)) {
ret = -1;
goto out;
}
rc = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
if (!rc)
rc = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
ret = blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL);
if (!ret)
ret = blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len);
if (rc || len == 0 || off == NULL)
if (ret || len == 0 || off == NULL) {
/*
* If lookup fails, the probe did not find any values, eg. for
* a file image or a loop device. Soft error.
*/
ret = 1;
goto out;
}
offset = strtoll(off, NULL, 10);
if (len > sizeof(buf))
len = sizeof(buf);
memset(buf, 0, len);
rc = pwrite(fd, buf, len, offset);
ret = pwrite(fd, buf, len, offset);
if (ret != len) {
fprintf(stderr, "ERROR: cannot wipe existing superblock\n");
ret = -1;
}
fsync(fd);
out:
blkid_free_probe(pr);
return;
return ret;
}
int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
@ -885,7 +897,12 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
return 1;
}
btrfs_wipe_existing_sb(fd);
ret = btrfs_wipe_existing_sb(fd);
if (ret < 0) {
fprintf(stderr, "ERROR: cannot wipe superblocks on '%s'\n",
file);
return 1;
}
*block_count_ret = block_count;
return 0;