X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=super-recover.c;h=880fd7712546c8287d8b9d315185c98982898658;hb=669ba89e52945e26528d498221c8ecd576b10d2d;hp=adb2c442996d0d0d6146109f28328ee7fcc0e452;hpb=38cfeef1033e254c0a1446fe6f4bbe6f30e1f5db;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/super-recover.c b/super-recover.c index adb2c44..880fd77 100644 --- a/super-recover.c +++ b/super-recover.c @@ -16,9 +16,6 @@ * Boston, MA 021110-1307, USA. */ -#define _XOPEN_SOURCE 500 -#define _GNU_SOURCE 1 - #include #include #include @@ -91,24 +88,6 @@ 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); - char result[csum_size]; - u32 crc = ~(u32)0; - - if (btrfs_super_bytenr(sb) != bytenr) - return 0; - if (sb->magic != cpu_to_le64(BTRFS_MAGIC)) - return 0; - - crc = btrfs_csum_data(NULL, (char *)sb + BTRFS_CSUM_SIZE, - crc, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); - btrfs_csum_final(crc, result); - - return !memcmp(sb, &result, csum_size); -} - static int add_superblock_record(struct btrfs_super_block *sb, char *fname, u64 bytenr, struct list_head *head) { @@ -136,24 +115,20 @@ read_dev_supers(char *filename, struct btrfs_recover_superblock *recover) int i, ret, fd; u8 buf[BTRFS_SUPER_INFO_SIZE]; u64 max_gen, bytenr; + struct btrfs_super_block *sb = (struct btrfs_super_block *)buf; + /* just ignore errno that were set in btrfs_scan_fs_devices() */ errno = 0; - struct btrfs_super_block *sb = (struct btrfs_super_block *)buf; - - fd = open(filename, O_RDONLY, 0666); + fd = open(filename, O_RDONLY); if (fd < 0) return -errno; for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); - ret = pread64(fd, buf, sizeof(buf), bytenr); - if (ret < sizeof(buf)) { - ret = -errno; - goto out; - } - ret = check_super(bytenr, sb); - if (ret) { + + ret = btrfs_read_dev_super(fd, sb, bytenr, SBREAD_DEFAULT); + if (!ret) { ret = add_superblock_record(sb, filename, bytenr, &recover->good_supers); if (ret) @@ -161,13 +136,18 @@ read_dev_supers(char *filename, struct btrfs_recover_superblock *recover) max_gen = btrfs_super_generation(sb); if (max_gen > recover->max_generation) recover->max_generation = max_gen; - } else { + } else if (ret != -ENOENT){ + /* + * Skip superblock which doesn't exist, only adds + * really corrupted superblock + */ ret = add_superblock_record(sb, filename, bytenr, &recover->bad_supers); if (ret) goto out; } } + ret = 0; out: close(fd); return ret; @@ -197,28 +177,6 @@ static int read_fs_supers(struct btrfs_recover_superblock *recover) return 0; } -static struct super_block_record *recover_get_good_super( - struct btrfs_recover_superblock *recover) -{ - struct super_block_record *record; - record = list_entry(recover->good_supers.next, - struct super_block_record, list); - return record; -} - -static void print_all_devices(struct list_head *devices) -{ - struct btrfs_device *dev; - - printf("All Devices:\n"); - list_for_each_entry(dev, devices, dev_list) { - printf("\t"); - printf("Device: id = %llu, name = %s\n", - dev->devid, dev->name); - } - printf("\n"); -} - static void print_super_info(struct super_block_record *record) { printf("\t\tdevice name = %s\n", record->device_name); @@ -282,7 +240,8 @@ int btrfs_recover_superblocks(const char *dname, } init_recover_superblock(&recover); - ret = btrfs_scan_fs_devices(fd, dname, &recover.fs_devices, 0, 1); + ret = btrfs_scan_fs_devices(fd, dname, &recover.fs_devices, 0, + SBREAD_RECOVER, 0); close(fd); if (ret) { ret = 1; @@ -312,16 +271,18 @@ int btrfs_recover_superblocks(const char *dname, goto no_recover; } } - record = recover_get_good_super(&recover); + record = list_first_entry(&recover.good_supers, + struct super_block_record, list); + root = open_ctree(record->device_name, record->bytenr, OPEN_CTREE_RECOVER_SUPER | OPEN_CTREE_WRITES); if (!root) { ret = 3; goto no_recover; } - /* reset super_bytenr in order that we will rewite all supers */ + /* reset super_bytenr in order that we will rewrite all supers */ root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET; - ret = write_all_supers(root); + ret = write_all_supers(root->fs_info); if (!ret) ret = 2; else @@ -331,7 +292,7 @@ int btrfs_recover_superblocks(const char *dname, no_recover: recover_err_str(ret); free_recover_superblock(&recover); - /* check if we have freed fs_deivces in close_ctree() */ + /* check if we have freed fs_devices in close_ctree() */ if (!root) btrfs_close_devices(recover.fs_devices); return ret;