btrfs-progs: remove temporary buffer for super block

There are a lot of call sites where we use the following code snippet:

	u8 super_block_data[BTRFS_SUPER_INFO_SIZE];
	struct btrfs_super_block *sb;
	u64 ret;

	sb = (struct btrfs_super_block *)super_block_data;

The reason for this is, structure btrfs_super_block was smaller than
BTRFS_SUPER_INFO_SIZE.

Thus for anything with csum involved, we have to use a proper 4K buffer.

Since the recent unification of sizeof(struct btrfs_super_block), we no
longer need such workaround, and can use struct btrfs_super_block
directly to do any operation.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Qu Wenruo 2021-10-21 09:40:19 +08:00 committed by David Sterba
parent 76f1a2ed57
commit 636b2e6027
12 changed files with 112 additions and 148 deletions

View File

@ -668,8 +668,7 @@ static int cmp_device_info(const void *a, const void *b)
int dev_to_fsid(const char *dev, u8 *fsid) int dev_to_fsid(const char *dev, u8 *fsid)
{ {
struct btrfs_super_block *disk_super; struct btrfs_super_block disk_super;
char buf[BTRFS_SUPER_INFO_SIZE];
int ret; int ret;
int fd; int fd;
@ -679,13 +678,12 @@ int dev_to_fsid(const char *dev, u8 *fsid)
return ret; return ret;
} }
disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, &disk_super,
ret = btrfs_read_dev_super(fd, disk_super,
BTRFS_SUPER_INFO_OFFSET, SBREAD_DEFAULT); BTRFS_SUPER_INFO_OFFSET, SBREAD_DEFAULT);
if (ret) if (ret)
goto out; goto out;
memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE); memcpy(fsid, disk_super.fsid, BTRFS_FSID_SIZE);
ret = 0; ret = 0;
out: out:

View File

@ -33,13 +33,10 @@
static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full, static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full,
int force) int force)
{ {
u8 super_block_data[BTRFS_SUPER_INFO_SIZE]; struct btrfs_super_block sb;
struct btrfs_super_block *sb;
u64 ret; u64 ret;
sb = (struct btrfs_super_block *)super_block_data; ret = sbread(fd, &sb, sb_bytenr);
ret = sbread(fd, super_block_data, sb_bytenr);
if (ret != BTRFS_SUPER_INFO_SIZE) { if (ret != BTRFS_SUPER_INFO_SIZE) {
/* check if the disk if too short for further superblock */ /* check if the disk if too short for further superblock */
if (ret == 0 && errno == 0) if (ret == 0 && errno == 0)
@ -52,11 +49,11 @@ static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full,
} }
printf("superblock: bytenr=%llu, device=%s\n", sb_bytenr, filename); printf("superblock: bytenr=%llu, device=%s\n", sb_bytenr, filename);
printf("---------------------------------------------------------\n"); printf("---------------------------------------------------------\n");
if (btrfs_super_magic(sb) != BTRFS_MAGIC && !force) { if (btrfs_super_magic(&sb) != BTRFS_MAGIC && !force) {
error("bad magic on superblock on %s at %llu", error("bad magic on superblock on %s at %llu",
filename, (unsigned long long)sb_bytenr); filename, (unsigned long long)sb_bytenr);
} else { } else {
btrfs_print_superblock(sb, full); btrfs_print_superblock(&sb, full);
} }
return 0; return 0;
} }

View File

@ -1506,8 +1506,7 @@ static int recover_prepare(struct recover_control *rc, const char *path)
{ {
int ret; int ret;
int fd; int fd;
struct btrfs_super_block *sb; struct btrfs_super_block sb;
char buf[BTRFS_SUPER_INFO_SIZE];
struct btrfs_fs_devices *fs_devices; struct btrfs_fs_devices *fs_devices;
ret = 0; ret = 0;
@ -1517,23 +1516,22 @@ static int recover_prepare(struct recover_control *rc, const char *path)
return -1; return -1;
} }
sb = (struct btrfs_super_block*)buf; ret = btrfs_read_dev_super(fd, &sb, BTRFS_SUPER_INFO_OFFSET,
ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET,
SBREAD_RECOVER); SBREAD_RECOVER);
if (ret) { if (ret) {
fprintf(stderr, "read super block error\n"); fprintf(stderr, "read super block error\n");
goto out_close_fd; goto out_close_fd;
} }
rc->sectorsize = btrfs_super_sectorsize(sb); rc->sectorsize = btrfs_super_sectorsize(&sb);
rc->nodesize = btrfs_super_nodesize(sb); rc->nodesize = btrfs_super_nodesize(&sb);
rc->generation = btrfs_super_generation(sb); rc->generation = btrfs_super_generation(&sb);
rc->chunk_root_generation = btrfs_super_chunk_root_generation(sb); rc->chunk_root_generation = btrfs_super_chunk_root_generation(&sb);
rc->csum_size = btrfs_super_csum_size(sb); rc->csum_size = btrfs_super_csum_size(&sb);
rc->csum_type = btrfs_super_csum_type(sb); rc->csum_type = btrfs_super_csum_type(&sb);
/* if seed, the result of scanning below will be partial */ /* if seed, the result of scanning below will be partial */
if (btrfs_super_flags(sb) & BTRFS_SUPER_FLAG_SEEDING) { if (btrfs_super_flags(&sb) & BTRFS_SUPER_FLAG_SEEDING) {
fprintf(stderr, "this device is seed device\n"); fprintf(stderr, "this device is seed device\n");
ret = -1; ret = -1;
goto out_close_fd; goto out_close_fd;

View File

@ -114,9 +114,8 @@ static int
read_dev_supers(char *filename, struct btrfs_recover_superblock *recover) read_dev_supers(char *filename, struct btrfs_recover_superblock *recover)
{ {
int i, ret, fd; int i, ret, fd;
u8 buf[BTRFS_SUPER_INFO_SIZE];
u64 max_gen, bytenr; u64 max_gen, bytenr;
struct btrfs_super_block *sb = (struct btrfs_super_block *)buf; struct btrfs_super_block sb;
/* just ignore errno that were set in btrfs_scan_fs_devices() */ /* just ignore errno that were set in btrfs_scan_fs_devices() */
errno = 0; errno = 0;
@ -128,13 +127,13 @@ read_dev_supers(char *filename, struct btrfs_recover_superblock *recover)
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
bytenr = btrfs_sb_offset(i); bytenr = btrfs_sb_offset(i);
ret = btrfs_read_dev_super(fd, sb, bytenr, SBREAD_DEFAULT); ret = btrfs_read_dev_super(fd, &sb, bytenr, SBREAD_DEFAULT);
if (!ret) { if (!ret) {
ret = add_superblock_record(sb, filename, bytenr, ret = add_superblock_record(&sb, filename, bytenr,
&recover->good_supers); &recover->good_supers);
if (ret) if (ret)
goto out; goto out;
max_gen = btrfs_super_generation(sb); max_gen = btrfs_super_generation(&sb);
if (max_gen > recover->max_generation) if (max_gen > recover->max_generation)
recover->max_generation = max_gen; recover->max_generation = max_gen;
} else if (ret != -ENOENT){ } else if (ret != -ENOENT){
@ -142,7 +141,7 @@ read_dev_supers(char *filename, struct btrfs_recover_superblock *recover)
* Skip superblock which doesn't exist, only adds * Skip superblock which doesn't exist, only adds
* really corrupted superblock * really corrupted superblock
*/ */
ret = add_superblock_record(sb, filename, bytenr, ret = add_superblock_record(&sb, filename, bytenr,
&recover->bad_supers); &recover->bad_supers);
if (ret) if (ret)
goto out; goto out;

View File

@ -269,34 +269,25 @@ int btrfs_register_all_devices(void)
int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
int super_offset) int super_offset)
{ {
struct btrfs_super_block *disk_super; struct btrfs_super_block disk_super;
char *buf;
int ret = 0; int ret = 0;
buf = malloc(BTRFS_SUPER_INFO_SIZE); ret = sbread(fd, &disk_super, super_offset);
if (!buf) {
ret = -ENOMEM;
goto out;
}
ret = sbread(fd, buf, super_offset);
if (ret != BTRFS_SUPER_INFO_SIZE) if (ret != BTRFS_SUPER_INFO_SIZE)
goto brelse; goto out;
ret = 0; ret = 0;
disk_super = (struct btrfs_super_block *)buf;
/* /*
* Accept devices from the same filesystem, allow partially created * Accept devices from the same filesystem, allow partially created
* structures. * structures.
*/ */
if (btrfs_super_magic(disk_super) != BTRFS_MAGIC && if (btrfs_super_magic(&disk_super) != BTRFS_MAGIC &&
btrfs_super_magic(disk_super) != BTRFS_MAGIC_TEMPORARY) btrfs_super_magic(&disk_super) != BTRFS_MAGIC_TEMPORARY)
goto brelse; goto out;
if (!memcmp(disk_super->fsid, root->fs_info->super_copy->fsid, if (!memcmp(disk_super.fsid, root->fs_info->super_copy->fsid,
BTRFS_FSID_SIZE)) BTRFS_FSID_SIZE))
ret = 1; ret = 1;
brelse:
free(buf);
out: out:
return ret; return ret;
} }

View File

@ -438,8 +438,7 @@ int get_fs_info(const char *path, struct btrfs_ioctl_fs_info_args *fi_args,
memset(fi_args, 0, sizeof(*fi_args)); memset(fi_args, 0, sizeof(*fi_args));
if (path_is_block_device(path) == 1) { if (path_is_block_device(path) == 1) {
struct btrfs_super_block *disk_super; struct btrfs_super_block disk_super;
char buf[BTRFS_SUPER_INFO_SIZE];
/* Ensure it's mounted, then set path to the mountpoint */ /* Ensure it's mounted, then set path to the mountpoint */
fd = open(path, O_RDONLY); fd = open(path, O_RDONLY);
@ -460,14 +459,13 @@ int get_fs_info(const char *path, struct btrfs_ioctl_fs_info_args *fi_args,
/* Only fill in this one device */ /* Only fill in this one device */
fi_args->num_devices = 1; fi_args->num_devices = 1;
disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, &disk_super,
ret = btrfs_read_dev_super(fd, disk_super,
BTRFS_SUPER_INFO_OFFSET, 0); BTRFS_SUPER_INFO_OFFSET, 0);
if (ret < 0) { if (ret < 0) {
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
last_devid = btrfs_stack_device_id(&disk_super->dev_item); last_devid = btrfs_stack_device_id(&disk_super.dev_item);
fi_args->max_id = last_devid; fi_args->max_id = last_devid;
memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE); memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE);

View File

@ -91,15 +91,13 @@ static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg,
u64 root_bytenr, u64 chunk_bytenr) u64 root_bytenr, u64 chunk_bytenr)
{ {
unsigned char chunk_uuid[BTRFS_UUID_SIZE]; unsigned char chunk_uuid[BTRFS_UUID_SIZE];
char super_buf[BTRFS_SUPER_INFO_SIZE]; struct btrfs_super_block super = {};
struct btrfs_super_block *super = (struct btrfs_super_block *)super_buf;
int ret; int ret;
memset(super_buf, 0, BTRFS_SUPER_INFO_SIZE);
cfg->num_bytes = round_down(cfg->num_bytes, cfg->sectorsize); cfg->num_bytes = round_down(cfg->num_bytes, cfg->sectorsize);
if (*cfg->fs_uuid) { if (*cfg->fs_uuid) {
if (uuid_parse(cfg->fs_uuid, super->fsid) != 0) { if (uuid_parse(cfg->fs_uuid, super.fsid) != 0) {
error("could not parse UUID: %s", cfg->fs_uuid); error("could not parse UUID: %s", cfg->fs_uuid);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
@ -108,43 +106,43 @@ static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg,
* Caller should make sure the uuid is either unique or OK to * Caller should make sure the uuid is either unique or OK to
* be duplicate in case it's copied from the source filesystem. * be duplicate in case it's copied from the source filesystem.
*/ */
uuid_copy(super->metadata_uuid, super->fsid); uuid_copy(super.metadata_uuid, super.fsid);
} else { } else {
uuid_generate(super->fsid); uuid_generate(super.fsid);
uuid_unparse(super->fsid, cfg->fs_uuid); uuid_unparse(super.fsid, cfg->fs_uuid);
uuid_copy(super->metadata_uuid, super->fsid); uuid_copy(super.metadata_uuid, super.fsid);
} }
uuid_generate(chunk_uuid); uuid_generate(chunk_uuid);
uuid_unparse(chunk_uuid, cfg->chunk_uuid); uuid_unparse(chunk_uuid, cfg->chunk_uuid);
btrfs_set_super_bytenr(super, cfg->super_bytenr); btrfs_set_super_bytenr(&super, cfg->super_bytenr);
btrfs_set_super_num_devices(super, 1); btrfs_set_super_num_devices(&super, 1);
btrfs_set_super_magic(super, BTRFS_MAGIC_TEMPORARY); btrfs_set_super_magic(&super, BTRFS_MAGIC_TEMPORARY);
btrfs_set_super_generation(super, 1); btrfs_set_super_generation(&super, 1);
btrfs_set_super_root(super, root_bytenr); btrfs_set_super_root(&super, root_bytenr);
btrfs_set_super_chunk_root(super, chunk_bytenr); btrfs_set_super_chunk_root(&super, chunk_bytenr);
btrfs_set_super_total_bytes(super, cfg->num_bytes); btrfs_set_super_total_bytes(&super, cfg->num_bytes);
/* /*
* Temporary filesystem will only have 6 tree roots: * Temporary filesystem will only have 6 tree roots:
* chunk tree, root tree, extent_tree, device tree, fs tree * chunk tree, root tree, extent_tree, device tree, fs tree
* and csum tree. * and csum tree.
*/ */
btrfs_set_super_bytes_used(super, 6 * cfg->nodesize); btrfs_set_super_bytes_used(&super, 6 * cfg->nodesize);
btrfs_set_super_sectorsize(super, cfg->sectorsize); btrfs_set_super_sectorsize(&super, cfg->sectorsize);
super->__unused_leafsize = cpu_to_le32(cfg->nodesize); super.__unused_leafsize = cpu_to_le32(cfg->nodesize);
btrfs_set_super_nodesize(super, cfg->nodesize); btrfs_set_super_nodesize(&super, cfg->nodesize);
btrfs_set_super_stripesize(super, cfg->stripesize); btrfs_set_super_stripesize(&super, cfg->stripesize);
btrfs_set_super_csum_type(super, cfg->csum_type); btrfs_set_super_csum_type(&super, cfg->csum_type);
btrfs_set_super_chunk_root(super, chunk_bytenr); btrfs_set_super_chunk_root(&super, chunk_bytenr);
btrfs_set_super_cache_generation(super, -1); btrfs_set_super_cache_generation(&super, -1);
btrfs_set_super_incompat_flags(super, cfg->features); btrfs_set_super_incompat_flags(&super, cfg->features);
if (cfg->label) if (cfg->label)
__strncpy_null(super->label, cfg->label, BTRFS_LABEL_SIZE - 1); __strncpy_null(super.label, cfg->label, BTRFS_LABEL_SIZE - 1);
/* Sys chunk array will be re-initialized at chunk tree init time */ /* Sys chunk array will be re-initialized at chunk tree init time */
super->sys_chunk_array_size = 0; super.sys_chunk_array_size = 0;
ret = write_temp_super(fd, super, cfg->super_bytenr); ret = write_temp_super(fd, &super, cfg->super_bytenr);
out: out:
return ret; return ret;
} }
@ -295,13 +293,12 @@ static int insert_temp_dev_item(int fd, struct extent_buffer *buf,
{ {
struct btrfs_disk_key disk_key; struct btrfs_disk_key disk_key;
struct btrfs_dev_item *dev_item; struct btrfs_dev_item *dev_item;
char super_buf[BTRFS_SUPER_INFO_SIZE];
unsigned char dev_uuid[BTRFS_UUID_SIZE]; unsigned char dev_uuid[BTRFS_UUID_SIZE];
unsigned char fsid[BTRFS_FSID_SIZE]; unsigned char fsid[BTRFS_FSID_SIZE];
struct btrfs_super_block *super = (struct btrfs_super_block *)super_buf; struct btrfs_super_block super;
int ret; int ret;
ret = pread(fd, super_buf, BTRFS_SUPER_INFO_SIZE, cfg->super_bytenr); ret = pread(fd, &super, BTRFS_SUPER_INFO_SIZE, cfg->super_bytenr);
if (ret < BTRFS_SUPER_INFO_SIZE) { if (ret < BTRFS_SUPER_INFO_SIZE) {
ret = (ret < 0 ? -errno : -EIO); ret = (ret < 0 ? -errno : -EIO);
goto out; goto out;
@ -342,9 +339,9 @@ static int insert_temp_dev_item(int fd, struct extent_buffer *buf,
btrfs_set_device_type(buf, dev_item, 0); btrfs_set_device_type(buf, dev_item, 0);
/* Super dev_item is not complete, copy the complete one to sb */ /* Super dev_item is not complete, copy the complete one to sb */
read_extent_buffer(buf, &super->dev_item, (unsigned long)dev_item, read_extent_buffer(buf, &super.dev_item, (unsigned long)dev_item,
sizeof(*dev_item)); sizeof(*dev_item));
ret = write_temp_super(fd, super, cfg->super_bytenr); ret = write_temp_super(fd, &super, cfg->super_bytenr);
(*slot)++; (*slot)++;
out: out:
return ret; return ret;
@ -357,12 +354,10 @@ static int insert_temp_chunk_item(int fd, struct extent_buffer *buf,
{ {
struct btrfs_chunk *chunk; struct btrfs_chunk *chunk;
struct btrfs_disk_key disk_key; struct btrfs_disk_key disk_key;
char super_buf[BTRFS_SUPER_INFO_SIZE]; struct btrfs_super_block sb;
struct btrfs_super_block *sb = (struct btrfs_super_block *)super_buf;
int ret = 0; int ret = 0;
ret = pread(fd, super_buf, BTRFS_SUPER_INFO_SIZE, ret = pread(fd, &sb, BTRFS_SUPER_INFO_SIZE, cfg->super_bytenr);
cfg->super_bytenr);
if (ret < BTRFS_SUPER_INFO_SIZE) { if (ret < BTRFS_SUPER_INFO_SIZE) {
ret = (ret < 0 ? ret : -EIO); ret = (ret < 0 ? ret : -EIO);
return ret; return ret;
@ -391,7 +386,7 @@ static int insert_temp_chunk_item(int fd, struct extent_buffer *buf,
btrfs_set_stripe_devid_nr(buf, chunk, 0, 1); btrfs_set_stripe_devid_nr(buf, chunk, 0, 1);
/* We are doing 1:1 mapping, so start is its dev offset */ /* We are doing 1:1 mapping, so start is its dev offset */
btrfs_set_stripe_offset_nr(buf, chunk, 0, start); btrfs_set_stripe_offset_nr(buf, chunk, 0, start);
write_extent_buffer(buf, &sb->dev_item.uuid, write_extent_buffer(buf, sb.dev_item.uuid,
(unsigned long)btrfs_stripe_dev_uuid_nr(chunk, 0), (unsigned long)btrfs_stripe_dev_uuid_nr(chunk, 0),
BTRFS_UUID_SIZE); BTRFS_UUID_SIZE);
(*slot)++; (*slot)++;
@ -403,18 +398,18 @@ static int insert_temp_chunk_item(int fd, struct extent_buffer *buf,
char *cur; char *cur;
u32 array_size; u32 array_size;
cur = (char *)sb->sys_chunk_array cur = (char *)sb.sys_chunk_array
+ btrfs_super_sys_array_size(sb); + btrfs_super_sys_array_size(&sb);
memcpy(cur, &disk_key, sizeof(disk_key)); memcpy(cur, &disk_key, sizeof(disk_key));
cur += sizeof(disk_key); cur += sizeof(disk_key);
read_extent_buffer(buf, cur, (unsigned long int)chunk, read_extent_buffer(buf, cur, (unsigned long int)chunk,
btrfs_chunk_item_size(1)); btrfs_chunk_item_size(1));
array_size = btrfs_super_sys_array_size(sb); array_size = btrfs_super_sys_array_size(&sb);
array_size += btrfs_chunk_item_size(1) + array_size += btrfs_chunk_item_size(1) +
sizeof(disk_key); sizeof(disk_key);
btrfs_set_super_sys_array_size(sb, array_size); btrfs_set_super_sys_array_size(&sb, array_size);
ret = write_temp_super(fd, sb, cfg->super_bytenr); ret = write_temp_super(fd, &sb, cfg->super_bytenr);
} }
return ret; return ret;
} }

View File

@ -1066,27 +1066,23 @@ err:
static int migrate_super_block(int fd, u64 old_bytenr) static int migrate_super_block(int fd, u64 old_bytenr)
{ {
int ret; int ret;
struct extent_buffer *buf; struct btrfs_super_block super;
struct btrfs_super_block *super; u8 result[BTRFS_CSUM_SIZE] = {};
u32 len; u32 len;
u32 bytenr; u32 bytenr;
buf = malloc(sizeof(*buf) + BTRFS_SUPER_INFO_SIZE); ret = pread(fd, &super, BTRFS_SUPER_INFO_SIZE, old_bytenr);
if (!buf)
return -ENOMEM;
buf->len = BTRFS_SUPER_INFO_SIZE;
ret = pread(fd, buf->data, BTRFS_SUPER_INFO_SIZE, old_bytenr);
if (ret != BTRFS_SUPER_INFO_SIZE) if (ret != BTRFS_SUPER_INFO_SIZE)
goto fail; goto fail;
super = (struct btrfs_super_block *)buf->data; BUG_ON(btrfs_super_bytenr(&super) != old_bytenr);
BUG_ON(btrfs_super_bytenr(super) != old_bytenr); btrfs_set_super_bytenr(&super, BTRFS_SUPER_INFO_OFFSET);
btrfs_set_super_bytenr(super, BTRFS_SUPER_INFO_OFFSET);
csum_tree_block_size(buf, btrfs_super_csum_size(super), btrfs_csum_data(NULL, btrfs_super_csum_type(&super),
0, btrfs_super_csum_type(super)); (u8 *)&super + BTRFS_CSUM_SIZE, result,
ret = pwrite(fd, buf->data, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
memcpy(&super.csum[0], result, BTRFS_CSUM_SIZE);
ret = pwrite(fd, &super , BTRFS_SUPER_INFO_SIZE,
BTRFS_SUPER_INFO_OFFSET); BTRFS_SUPER_INFO_OFFSET);
if (ret != BTRFS_SUPER_INFO_SIZE) if (ret != BTRFS_SUPER_INFO_SIZE)
goto fail; goto fail;
@ -1095,12 +1091,12 @@ static int migrate_super_block(int fd, u64 old_bytenr)
if (ret) if (ret)
goto fail; goto fail;
memset(buf->data, 0, BTRFS_SUPER_INFO_SIZE); memset(&super, 0, BTRFS_SUPER_INFO_SIZE);
for (bytenr = 0; bytenr < BTRFS_SUPER_INFO_OFFSET; ) { for (bytenr = 0; bytenr < BTRFS_SUPER_INFO_OFFSET; ) {
len = BTRFS_SUPER_INFO_OFFSET - bytenr; len = BTRFS_SUPER_INFO_OFFSET - bytenr;
if (len > BTRFS_SUPER_INFO_SIZE) if (len > BTRFS_SUPER_INFO_SIZE)
len = BTRFS_SUPER_INFO_SIZE; len = BTRFS_SUPER_INFO_SIZE;
ret = pwrite(fd, buf->data, len, bytenr); ret = pwrite(fd, &super, len, bytenr);
if (ret != len) { if (ret != len) {
fprintf(stderr, "unable to zero fill device\n"); fprintf(stderr, "unable to zero fill device\n");
break; break;
@ -1110,7 +1106,6 @@ static int migrate_super_block(int fd, u64 old_bytenr)
ret = 0; ret = 0;
fsync(fd); fsync(fd);
fail: fail:
free(buf);
if (ret > 0) if (ret > 0)
ret = -1; ret = -1;
return ret; return ret;

View File

@ -2927,12 +2927,11 @@ static int update_disk_super_on_device(struct btrfs_fs_info *info,
struct extent_buffer *leaf; struct extent_buffer *leaf;
struct btrfs_path path; struct btrfs_path path;
struct btrfs_dev_item *dev_item; struct btrfs_dev_item *dev_item;
struct btrfs_super_block *disk_super; struct btrfs_super_block disk_super;
char dev_uuid[BTRFS_UUID_SIZE]; char dev_uuid[BTRFS_UUID_SIZE];
char fs_uuid[BTRFS_UUID_SIZE]; char fs_uuid[BTRFS_UUID_SIZE];
u64 devid, type, io_align, io_width; u64 devid, type, io_align, io_width;
u64 sector_size, total_bytes, bytes_used; u64 sector_size, total_bytes, bytes_used;
char buf[BTRFS_SUPER_INFO_SIZE];
int fp = -1; int fp = -1;
int ret; int ret;
@ -2982,10 +2981,9 @@ static int update_disk_super_on_device(struct btrfs_fs_info *info,
goto out; goto out;
} }
memcpy(buf, info->super_copy, BTRFS_SUPER_INFO_SIZE); memcpy(&disk_super, info->super_copy, BTRFS_SUPER_INFO_SIZE);
disk_super = (struct btrfs_super_block *)buf; dev_item = &disk_super.dev_item;
dev_item = &disk_super->dev_item;
btrfs_set_stack_device_type(dev_item, type); btrfs_set_stack_device_type(dev_item, type);
btrfs_set_stack_device_id(dev_item, devid); btrfs_set_stack_device_id(dev_item, devid);
@ -2996,9 +2994,9 @@ static int update_disk_super_on_device(struct btrfs_fs_info *info,
btrfs_set_stack_device_sector_size(dev_item, sector_size); btrfs_set_stack_device_sector_size(dev_item, sector_size);
memcpy(dev_item->uuid, dev_uuid, BTRFS_UUID_SIZE); memcpy(dev_item->uuid, dev_uuid, BTRFS_UUID_SIZE);
memcpy(dev_item->fsid, fs_uuid, BTRFS_UUID_SIZE); memcpy(dev_item->fsid, fs_uuid, BTRFS_UUID_SIZE);
csum_block((u8 *)buf, BTRFS_SUPER_INFO_SIZE); csum_block((u8 *)&disk_super, BTRFS_SUPER_INFO_SIZE);
ret = pwrite64(fp, buf, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET); ret = pwrite64(fp, &disk_super, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET);
if (ret != BTRFS_SUPER_INFO_SIZE) { if (ret != BTRFS_SUPER_INFO_SIZE) {
if (ret < 0) { if (ret < 0) {
errno = ret; errno = ret;
@ -3010,7 +3008,7 @@ static int update_disk_super_on_device(struct btrfs_fs_info *info,
goto out; goto out;
} }
write_backup_supers(fp, (u8 *)buf); write_backup_supers(fp, (u8 *)&disk_super);
out: out:
if (fp != -1) if (fp != -1)

View File

@ -1619,8 +1619,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
u8 fsid[BTRFS_FSID_SIZE]; u8 fsid[BTRFS_FSID_SIZE];
u8 metadata_uuid[BTRFS_FSID_SIZE]; u8 metadata_uuid[BTRFS_FSID_SIZE];
int fsid_is_initialized = 0; int fsid_is_initialized = 0;
char tmp[BTRFS_SUPER_INFO_SIZE]; struct btrfs_super_block buf;
struct btrfs_super_block *buf = (struct btrfs_super_block *)tmp;
int i; int i;
int ret; int ret;
int max_super = sbflags & SBREAD_RECOVER ? BTRFS_SUPER_MIRROR_MAX : 1; int max_super = sbflags & SBREAD_RECOVER ? BTRFS_SUPER_MIRROR_MAX : 1;
@ -1629,7 +1628,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
u64 bytenr; u64 bytenr;
if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) { if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) {
ret = sbread(fd, buf, sb_bytenr); ret = sbread(fd, &buf, sb_bytenr);
/* real error */ /* real error */
if (ret < 0) if (ret < 0)
return -errno; return -errno;
@ -1638,13 +1637,13 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
if (ret < BTRFS_SUPER_INFO_SIZE) if (ret < BTRFS_SUPER_INFO_SIZE)
return -ENOENT; return -ENOENT;
if (btrfs_super_bytenr(buf) != sb_bytenr) if (btrfs_super_bytenr(&buf) != sb_bytenr)
return -EIO; return -EIO;
ret = btrfs_check_super(buf, sbflags); ret = btrfs_check_super(&buf, sbflags);
if (ret < 0) if (ret < 0)
return ret; return ret;
memcpy(sb, buf, BTRFS_SUPER_INFO_SIZE); memcpy(sb, &buf, BTRFS_SUPER_INFO_SIZE);
return 0; return 0;
} }
@ -1657,31 +1656,31 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
for (i = 0; i < max_super; i++) { for (i = 0; i < max_super; i++) {
bytenr = btrfs_sb_offset(i); bytenr = btrfs_sb_offset(i);
ret = sbread(fd, buf, bytenr); ret = sbread(fd, &buf, bytenr);
if (ret < BTRFS_SUPER_INFO_SIZE) if (ret < BTRFS_SUPER_INFO_SIZE)
break; break;
if (btrfs_super_bytenr(buf) != bytenr ) if (btrfs_super_bytenr(&buf) != bytenr )
continue; continue;
/* if magic is NULL, the device was removed */ /* if magic is NULL, the device was removed */
if (btrfs_super_magic(buf) == 0 && i == 0) if (btrfs_super_magic(&buf) == 0 && i == 0)
break; break;
if (btrfs_check_super(buf, sbflags)) if (btrfs_check_super(&buf, sbflags))
continue; continue;
if (!fsid_is_initialized) { if (!fsid_is_initialized) {
if (btrfs_super_incompat_flags(buf) & if (btrfs_super_incompat_flags(&buf) &
BTRFS_FEATURE_INCOMPAT_METADATA_UUID) { BTRFS_FEATURE_INCOMPAT_METADATA_UUID) {
metadata_uuid_set = true; metadata_uuid_set = true;
memcpy(metadata_uuid, buf->metadata_uuid, memcpy(metadata_uuid, buf.metadata_uuid,
sizeof(metadata_uuid)); sizeof(metadata_uuid));
} }
memcpy(fsid, buf->fsid, sizeof(fsid)); memcpy(fsid, buf.fsid, sizeof(fsid));
fsid_is_initialized = 1; fsid_is_initialized = 1;
} else if (memcmp(fsid, buf->fsid, sizeof(fsid)) || } else if (memcmp(fsid, buf.fsid, sizeof(fsid)) ||
(metadata_uuid_set && memcmp(metadata_uuid, (metadata_uuid_set && memcmp(metadata_uuid,
buf->metadata_uuid, buf.metadata_uuid,
sizeof(metadata_uuid)))) { sizeof(metadata_uuid)))) {
/* /*
* the superblocks (the original one and * the superblocks (the original one and
@ -1691,9 +1690,9 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
continue; continue;
} }
if (btrfs_super_generation(buf) > transid) { if (btrfs_super_generation(&buf) > transid) {
memcpy(sb, buf, BTRFS_SUPER_INFO_SIZE); memcpy(sb, &buf, BTRFS_SUPER_INFO_SIZE);
transid = btrfs_super_generation(buf); transid = btrfs_super_generation(&buf);
} }
} }

View File

@ -541,22 +541,20 @@ int btrfs_scan_one_device(int fd, const char *path,
struct btrfs_fs_devices **fs_devices_ret, struct btrfs_fs_devices **fs_devices_ret,
u64 *total_devs, u64 super_offset, unsigned sbflags) u64 *total_devs, u64 super_offset, unsigned sbflags)
{ {
struct btrfs_super_block *disk_super; struct btrfs_super_block disk_super;
char buf[BTRFS_SUPER_INFO_SIZE];
int ret; int ret;
u64 devid; u64 devid;
disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, &disk_super, super_offset, sbflags);
ret = btrfs_read_dev_super(fd, disk_super, super_offset, sbflags);
if (ret < 0) if (ret < 0)
return -EIO; return -EIO;
devid = btrfs_stack_device_id(&disk_super->dev_item); devid = btrfs_stack_device_id(&disk_super.dev_item);
if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_METADUMP) if (btrfs_super_flags(&disk_super) & BTRFS_SUPER_FLAG_METADUMP)
*total_devs = 1; *total_devs = 1;
else else
*total_devs = btrfs_super_num_devices(disk_super); *total_devs = btrfs_super_num_devices(&disk_super);
ret = device_list_add(path, disk_super, devid, fs_devices_ret); ret = device_list_add(path, &disk_super, devid, fs_devices_ret);
return ret; return ret;
} }

View File

@ -805,19 +805,17 @@ static int check_btrfs_signature_zoned(const char *device)
{ {
int fd; int fd;
int ret; int ret;
char buf[BTRFS_SUPER_INFO_SIZE]; struct btrfs_super_block sb;
struct btrfs_super_block *sb;
fd = open(device, O_RDONLY); fd = open(device, O_RDONLY);
if (fd < 0) if (fd < 0)
return -1; return -1;
ret = pread(fd, buf, BTRFS_SUPER_INFO_SIZE, 0); ret = pread(fd, &sb, BTRFS_SUPER_INFO_SIZE, 0);
if (ret < 0) { if (ret < 0) {
ret = -1; ret = -1;
goto out; goto out;
} }
sb = (struct btrfs_super_block *)buf; if (btrfs_super_magic(&sb) == BTRFS_MAGIC)
if (btrfs_super_magic(sb) == BTRFS_MAGIC)
ret = 1; ret = 1;
else else
ret = 0; ret = 0;