btrfs-progs: super-recover: fix double free fs_devices memory

super-recover collects btrfs devices infomation using existed
functions scan_one_devices().

Problem is fs_devices is freed twice in close_ctree() and
free_recover_superblock() for super correction path.

Fix this problem by checking whether fs_devices memory
have been freed before we free it.

Cc: Eric Sandeen <sandeen@redhat.com>
Cc: Chris Murphy <lists@colorremedies.com>
Acked-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Wang Shilong <wangshilong1991@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
This commit is contained in:
Wang Shilong 2014-09-18 05:01:12 -04:00 committed by David Sterba
parent d0b24918f6
commit 0d84aa903a

View File

@ -69,21 +69,11 @@ void init_recover_superblock(struct btrfs_recover_superblock *recover)
static
void free_recover_superblock(struct btrfs_recover_superblock *recover)
{
struct btrfs_device *device;
struct super_block_record *record;
if (!recover->fs_devices)
return;
while (!list_empty(&recover->fs_devices->devices)) {
device = list_entry(recover->fs_devices->devices.next,
struct btrfs_device, dev_list);
list_del_init(&device->dev_list);
free(device->name);
free(device);
}
free(recover->fs_devices);
while (!list_empty(&recover->good_supers)) {
record = list_entry(recover->good_supers.next,
struct super_block_record, list);
@ -341,6 +331,9 @@ 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() */
if (!root)
btrfs_close_devices(recover.fs_devices);
return ret;
}