diff -ur btrfs-progs-0.20.rc1.20121017git91d9eec.old/disk-io.c btrfs-progs-0.20.rc1.20121017git91d9eec/disk-io.c --- btrfs-progs-0.20.rc1.20121017git91d9eec.old/disk-io.c 2013-02-13 11:04:05.361458311 +0000 +++ btrfs-progs-0.20.rc1.20121017git91d9eec/disk-io.c 2013-02-13 11:04:22.513377018 +0000 @@ -634,6 +634,9 @@ if (sb_bytenr == 0) sb_bytenr = BTRFS_SUPER_INFO_OFFSET; + /* try to drop all the caches */ + posix_fadvise(fp, 0, 0, POSIX_FADV_DONTNEED); + ret = btrfs_scan_one_device(fp, path, &fs_devices, &total_devs, sb_bytenr); @@ -1083,6 +1086,10 @@ list = &fs_info->fs_devices->devices; list_for_each_safe(next, tmp, list) { device = list_entry(next, struct btrfs_device, dev_list); + if (device->fd) { + fsync(device->fd); + posix_fadvise(device->fd, 0, 0, POSIX_FADV_DONTNEED); + } close(device->fd); list_del(&device->dev_list); free(device->name); diff -ur btrfs-progs-0.20.rc1.20121017git91d9eec.old/disk-io.c.orig btrfs-progs-0.20.rc1.20121017git91d9eec/disk-io.c.orig --- btrfs-progs-0.20.rc1.20121017git91d9eec.old/disk-io.c.orig 2012-10-05 01:35:31.000000000 +0100 +++ btrfs-progs-0.20.rc1.20121017git91d9eec/disk-io.c.orig 2013-02-13 11:04:05.361458311 +0000 @@ -458,8 +458,10 @@ u64 blocknr = btrfs_super_log_root(disk_super); struct btrfs_root *log_root = malloc(sizeof(struct btrfs_root)); - if (blocknr == 0) + if (blocknr == 0) { + free(log_root); return 0; + } blocksize = btrfs_level_size(tree_root, btrfs_super_log_root_level(disk_super)); @@ -622,7 +624,7 @@ struct btrfs_root *chunk_root = malloc(sizeof(struct btrfs_root)); struct btrfs_root *dev_root = malloc(sizeof(struct btrfs_root)); struct btrfs_root *csum_root = malloc(sizeof(struct btrfs_root)); - struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info)); + struct btrfs_fs_info *fs_info = malloc(sizeof(struct btrfs_fs_info)); int ret; struct btrfs_super_block *disk_super; struct btrfs_fs_devices *fs_devices = NULL; @@ -646,7 +648,7 @@ goto out; } - memset(fs_info, 0, sizeof(*fs_info)); + memset(fs_info, 0, sizeof(struct btrfs_fs_info)); fs_info->tree_root = tree_root; fs_info->extent_root = extent_root; fs_info->chunk_root = chunk_root; @@ -1075,15 +1077,19 @@ { struct list_head *list; struct list_head *next; + struct list_head *tmp; struct btrfs_device *device; - return 0; - list = &fs_info->fs_devices->devices; - list_for_each(next, list) { + list_for_each_safe(next, tmp, list) { device = list_entry(next, struct btrfs_device, dev_list); close(device->fd); + list_del(&device->dev_list); + free(device->name); + free(device->label); + free(device); } + free(fs_info->fs_devices); return 0; } @@ -1133,12 +1139,14 @@ extent_io_tree_cleanup(&fs_info->pinned_extents); extent_io_tree_cleanup(&fs_info->pending_del); extent_io_tree_cleanup(&fs_info->extent_ins); + btrfs_mapping_tree_free(&fs_info->mapping_tree); free(fs_info->tree_root); free(fs_info->extent_root); free(fs_info->chunk_root); free(fs_info->dev_root); free(fs_info->csum_root); + free(fs_info->log_root_tree); free(fs_info); return 0; diff -ur btrfs-progs-0.20.rc1.20121017git91d9eec.old/volumes.c btrfs-progs-0.20.rc1.20121017git91d9eec/volumes.c --- btrfs-progs-0.20.rc1.20121017git91d9eec.old/volumes.c 2013-02-13 11:04:05.411458074 +0000 +++ btrfs-progs-0.20.rc1.20121017git91d9eec/volumes.c 2013-02-13 11:04:22.514377013 +0000 @@ -176,6 +176,8 @@ goto fail; } + posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); + if (device->devid == fs_devices->latest_devid) fs_devices->latest_bdev = fd; if (device->devid == fs_devices->lowest_devid)