Superblock is always 4k, but metadata blocks may be larger. We have to
use the appropriate block size when doing checksums, otherwise they're
wrong.

Signed-off-by: David Sterba <dste...@suse.cz>
---
 btrfs-image.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/btrfs-image.c b/btrfs-image.c
index 188291c..dca7a28 100644
--- a/btrfs-image.c
+++ b/btrfs-image.c
@@ -469,6 +469,16 @@ static int read_data_extent(struct metadump_struct *md,
        return 0;
 }
 
+static int is_sb_offset(u64 offset) {
+       switch (offset) {
+               case 65536:
+               case 67108864:
+               case 274877906944:
+                       return 1;
+       }
+       return 0;
+}
+
 static int flush_pending(struct metadump_struct *md, int done)
 {
        struct async_work *async = NULL;
@@ -506,7 +516,16 @@ static int flush_pending(struct metadump_struct *md, int 
done)
                }
 
                while (!md->data && size > 0) {
-                       eb = read_tree_block(md->root, start, blocksize, 0);
+                       /*
+                        * We must differentiate between superblock and
+                        * metadata on filesystems with blocksize > 4k,
+                        * otherwise the checksum fails for superblock
+                        */
+                       int bs = blocksize;
+
+                       if (is_sb_offset(start))
+                               bs = BTRFS_SUPER_INFO_SIZE;
+                       eb = read_tree_block(md->root, start, bs, 0);
                        if (!eb) {
                                free(async->buffer);
                                free(async);
@@ -516,9 +535,9 @@ static int flush_pending(struct metadump_struct *md, int 
done)
                        }
                        copy_buffer(async->buffer + offset, eb);
                        free_extent_buffer(eb);
-                       start += blocksize;
-                       offset += blocksize;
-                       size -= blocksize;
+                       start += bs;
+                       offset += bs;
+                       size -= bs;
                }
 
                md->pending_start = (u64)-1;
-- 
1.8.2

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to