On 14.05.19 г. 16:58 ч., Johannes Thumshirn wrote:
> inspect-internal dump-superblock's load_and_dump_sb() already reads a
> super block from a file descriptor and places it into a 'struct
> btrfs_super_block'.
>
> For inspect-internal dump-csum we need this super block as well but don't
> care about printing it.
>
> Separate the read from the dump phase so we can re-use it elsewhere.
>
> Signed-off-by: Johannes Thumshirn <jthumsh...@suse.de>
Reviewed-by: Nikolay Borisov <nbori...@suse.com>
> ---
> - Fix double sizeof() @!$#$ (Nikolay)
>
> cmds-inspect-dump-super.c | 15 ++++++---------
> utils.c | 15 +++++++++++++++
> utils.h | 2 ++
> 3 files changed, 23 insertions(+), 9 deletions(-)
>
> diff --git a/cmds-inspect-dump-super.c b/cmds-inspect-dump-super.c
> index 7815c863f2ed..879f979f526a 100644
> --- a/cmds-inspect-dump-super.c
> +++ b/cmds-inspect-dump-super.c
> @@ -477,16 +477,13 @@ static void dump_superblock(struct btrfs_super_block
> *sb, int full)
> static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full,
> int force)
> {
> - u8 super_block_data[BTRFS_SUPER_INFO_SIZE];
> - struct btrfs_super_block *sb;
> + struct btrfs_super_block sb;
> u64 ret;
>
> - sb = (struct btrfs_super_block *)super_block_data;
> -
> - ret = pread64(fd, super_block_data, BTRFS_SUPER_INFO_SIZE, sb_bytenr);
> - if (ret != BTRFS_SUPER_INFO_SIZE) {
> + ret = load_sb(fd, sb_bytenr, &sb);
> + if (ret) {
> /* check if the disk if too short for further superblock */
> - if (ret == 0 && errno == 0)
> + if (ret == -ENOSPC)
> return 0;
>
> error("failed to read the superblock on %s at %llu",
> @@ -496,11 +493,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("---------------------------------------------------------\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",
> filename, (unsigned long long)sb_bytenr);
> } else {
> - dump_superblock(sb, full);
> + dump_superblock(&sb, full);
> }
> return 0;
> }
> diff --git a/utils.c b/utils.c
> index 9e26c884cc6c..f0ae53ded315 100644
> --- a/utils.c
> +++ b/utils.c
> @@ -2593,3 +2593,18 @@ void print_all_devices(struct list_head *devices)
> print_device_info(dev, "\t");
> printf("\n");
> }
> +
> +int load_sb(int fd, u64 bytenr, struct btrfs_super_block *sb)
> +{
> + size_t size = sizeof(struct btrfs_super_block);
> + int ret;
> +
> + ret = pread64(fd, sb, size, bytenr);
> + if (ret != size) {
> + if (ret == 0 && errno == 0)
> + return -EINVAL;
> +
> + return -errno;
> + }
> + return 0;
> +}
> diff --git a/utils.h b/utils.h
> index 7c5eb798557d..f0b9ec372893 100644
> --- a/utils.h
> +++ b/utils.h
> @@ -171,6 +171,8 @@ unsigned long total_memory(void);
> void print_device_info(struct btrfs_device *device, char *prefix);
> void print_all_devices(struct list_head *devices);
>
> +int load_sb(int fd, u64 bytenr, struct btrfs_super_block *sb);
> +
> /*
> * Global program state, configurable by command line and available to
> * functions without extra context passing.
>