diff options
-rw-r--r-- | utils.c | 58 |
1 files changed, 20 insertions, 38 deletions
@@ -585,25 +585,23 @@ static int zero_blocks(int fd, off_t start, size_t len) return ret; } -static int zero_dev_start(int fd) +#define ZERO_DEV_BYTES (2 * 1024 * 1024) + +/* don't write outside the device by clamping the region to the device size */ +static int zero_dev_clamped(int fd, off_t start, ssize_t len, u64 dev_size) { - off_t start = 0; - size_t len = 2 * 1024 * 1024; + off_t end = max(start, start + len); #ifdef __sparc__ - /* don't overwrite the disk labels on sparc */ - start = 1024; - len -= 1024; + /* and don't overwrite the disk labels on sparc */ + start = max(start, 1024); + end = max(end, 1024); #endif - return zero_blocks(fd, start, len); -} -static int zero_dev_end(int fd, u64 dev_size) -{ - size_t len = 2 * 1024 * 1024; - off_t start = dev_size - len; + start = min_t(u64, start, dev_size); + end = min_t(u64, end, dev_size); - return zero_blocks(fd, start, len); + return zero_blocks(fd, start, end - start); } int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, @@ -684,7 +682,6 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, u64 max_block_count, int *mixed, int discard) { u64 block_count; - u64 bytenr; struct stat st; int i, ret; @@ -720,36 +717,21 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, } } - ret = zero_dev_start(fd); - if (ret) - goto zero_dev_error; - - for (i = 0 ; i < BTRFS_SUPER_MIRROR_MAX; i++) { - bytenr = btrfs_sb_offset(i); - if (bytenr >= block_count) - break; - ret = zero_blocks(fd, bytenr, BTRFS_SUPER_INFO_SIZE); - if (ret) - goto zero_dev_error; - } + ret = zero_dev_clamped(fd, 0, ZERO_DEV_BYTES, block_count); + for (i = 0 ; !ret && i < BTRFS_SUPER_MIRROR_MAX; i++) + ret = zero_dev_clamped(fd, btrfs_sb_offset(i), + BTRFS_SUPER_INFO_SIZE, block_count); + if (!ret && zero_end) + ret = zero_dev_clamped(fd, block_count - ZERO_DEV_BYTES, + ZERO_DEV_BYTES, block_count); - if (zero_end) { - ret = zero_dev_end(fd, block_count); - if (ret) - goto zero_dev_error; - } - *block_count_ret = block_count; - -zero_dev_error: if (ret < 0) { fprintf(stderr, "ERROR: failed to zero device '%s' - %s\n", file, strerror(-ret)); return 1; - } else if (ret > 0) { - fprintf(stderr, "ERROR: failed to zero device '%s' - %d\n", - file, ret); - return 1; } + + *block_count_ret = block_count; return 0; } |