Message ID | dfe1eed9-2aac-a6b6-c681-93d74d4fd83d@thehawken.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
At 09/20/2016 08:38 AM, hawken wrote: > Hi! > > In super-recover.c, around line 96, check_super calls > btrfs_super_csum_size, which then dies because the size was too big. > I have solved this by reimplementing that stub inside super-recover.c > with error handling rather than crashing: > > diff --git a/super-recover.c b/super-recover.c > index adb2c44..2508e06 100644 > --- a/super-recover.c > +++ b/super-recover.c > @@ -93,7 +93,11 @@ void free_recover_superblock(struct > btrfs_recover_superblock *recover) > > static int check_super(u64 bytenr, struct btrfs_super_block *sb) > { > - int csum_size = btrfs_super_csum_size(sb); > + int t = btrfs_super_csum_type(sb); > + if(t >= ARRAY_SIZE(btrfs_csum_sizes)) > + return 0; > + int csum_size = btrfs_csum_sizes[t]; > + > char result[csum_size]; > u32 crc = ~(u32)0; Oh, we have only fixed check_super() in disk_io.c, forgot this one. We need to merge it with the one in disk_io.c, which checks super more comprehensively. Nice one. Thanks, Qu > > > (Sorry for bad formatting) > This allowed me to recover my superblocks > > I found this bug kind of ironic because a routine made to discover bad > data, crashed because it encountered bad data :D > > - hawken > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/super-recover.c b/super-recover.c index adb2c44..2508e06 100644 --- a/super-recover.c +++ b/super-recover.c @@ -93,7 +93,11 @@ void free_recover_superblock(struct btrfs_recover_superblock *recover) static int check_super(u64 bytenr, struct btrfs_super_block *sb) { - int csum_size = btrfs_super_csum_size(sb); + int t = btrfs_super_csum_type(sb); + if(t >= ARRAY_SIZE(btrfs_csum_sizes)) + return 0; + int csum_size = btrfs_csum_sizes[t]; + char result[csum_size]; u32 crc = ~(u32)0;