diff mbox series

[v3.1,1/3] btrfs-progs: factor out super_block reading from load_and_dump_sb

Message ID 20190514135804.18669-1-jthumshirn@suse.de (mailing list archive)
State New, archived
Headers show
Series [v3.1,1/3] btrfs-progs: factor out super_block reading from load_and_dump_sb | expand

Commit Message

Johannes Thumshirn May 14, 2019, 1:58 p.m. UTC
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 <jthumshirn@suse.de>
---
- Fix double sizeof() @!$#$ (Nikolay)

 cmds-inspect-dump-super.c | 15 ++++++---------
 utils.c                   | 15 +++++++++++++++
 utils.h                   |  2 ++
 3 files changed, 23 insertions(+), 9 deletions(-)

Comments

Nikolay Borisov May 14, 2019, 2 p.m. UTC | #1
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 <jthumshirn@suse.de>

Reviewed-by: Nikolay Borisov <nborisov@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.
>
Johannes Thumshirn May 16, 2019, 12:52 p.m. UTC | #2
On Tue, May 14, 2019 at 03:58:04PM +0200, 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 <jthumshirn@suse.de>
> ---
> - 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) {

This is buggy. We need to copy the whole BTRFS_SUPER_INFO_SIZE and calculate
the checksums over this area.

Sorry,
	Johannes
diff mbox series

Patch

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.