diff --git a/utils.c b/utils.c index 220c7d87..52791b53 100644 --- a/utils.c +++ b/utils.c @@ -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;