diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
| -rw-r--r-- | fs/btrfs/volumes.c | 55 |
1 files changed, 21 insertions, 34 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 3451e1cca2b5..1316139bf9e8 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/buffer_head.h> | 20 | #include <linux/buffer_head.h> |
| 21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
| 22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
| 23 | #include <linux/version.h> | ||
| 24 | #include <asm/div64.h> | 23 | #include <asm/div64.h> |
| 25 | #include "compat.h" | 24 | #include "compat.h" |
| 26 | #include "ctree.h" | 25 | #include "ctree.h" |
| @@ -104,10 +103,8 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, | |||
| 104 | u64 devid, u8 *uuid) | 103 | u64 devid, u8 *uuid) |
| 105 | { | 104 | { |
| 106 | struct btrfs_device *dev; | 105 | struct btrfs_device *dev; |
| 107 | struct list_head *cur; | ||
| 108 | 106 | ||
| 109 | list_for_each(cur, head) { | 107 | list_for_each_entry(dev, head, dev_list) { |
| 110 | dev = list_entry(cur, struct btrfs_device, dev_list); | ||
| 111 | if (dev->devid == devid && | 108 | if (dev->devid == devid && |
| 112 | (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { | 109 | (!uuid || !memcmp(dev->uuid, uuid, BTRFS_UUID_SIZE))) { |
| 113 | return dev; | 110 | return dev; |
| @@ -118,11 +115,9 @@ static noinline struct btrfs_device *__find_device(struct list_head *head, | |||
| 118 | 115 | ||
| 119 | static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) | 116 | static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) |
| 120 | { | 117 | { |
| 121 | struct list_head *cur; | ||
| 122 | struct btrfs_fs_devices *fs_devices; | 118 | struct btrfs_fs_devices *fs_devices; |
| 123 | 119 | ||
| 124 | list_for_each(cur, &fs_uuids) { | 120 | list_for_each_entry(fs_devices, &fs_uuids, list) { |
| 125 | fs_devices = list_entry(cur, struct btrfs_fs_devices, list); | ||
| 126 | if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) | 121 | if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) |
| 127 | return fs_devices; | 122 | return fs_devices; |
| 128 | } | 123 | } |
| @@ -159,6 +154,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) | |||
| 159 | loop: | 154 | loop: |
| 160 | spin_lock(&device->io_lock); | 155 | spin_lock(&device->io_lock); |
| 161 | 156 | ||
| 157 | loop_lock: | ||
| 162 | /* take all the bios off the list at once and process them | 158 | /* take all the bios off the list at once and process them |
| 163 | * later on (without the lock held). But, remember the | 159 | * later on (without the lock held). But, remember the |
| 164 | * tail and other pointers so the bios can be properly reinserted | 160 | * tail and other pointers so the bios can be properly reinserted |
| @@ -208,7 +204,7 @@ loop: | |||
| 208 | * is now congested. Back off and let other work structs | 204 | * is now congested. Back off and let other work structs |
| 209 | * run instead | 205 | * run instead |
| 210 | */ | 206 | */ |
| 211 | if (pending && bdi_write_congested(bdi) && | 207 | if (pending && bdi_write_congested(bdi) && num_run > 16 && |
| 212 | fs_info->fs_devices->open_devices > 1) { | 208 | fs_info->fs_devices->open_devices > 1) { |
| 213 | struct bio *old_head; | 209 | struct bio *old_head; |
| 214 | 210 | ||
| @@ -220,7 +216,8 @@ loop: | |||
| 220 | tail->bi_next = old_head; | 216 | tail->bi_next = old_head; |
| 221 | else | 217 | else |
| 222 | device->pending_bio_tail = tail; | 218 | device->pending_bio_tail = tail; |
| 223 | device->running_pending = 0; | 219 | |
| 220 | device->running_pending = 1; | ||
| 224 | 221 | ||
| 225 | spin_unlock(&device->io_lock); | 222 | spin_unlock(&device->io_lock); |
| 226 | btrfs_requeue_work(&device->work); | 223 | btrfs_requeue_work(&device->work); |
| @@ -229,6 +226,11 @@ loop: | |||
| 229 | } | 226 | } |
| 230 | if (again) | 227 | if (again) |
| 231 | goto loop; | 228 | goto loop; |
| 229 | |||
| 230 | spin_lock(&device->io_lock); | ||
| 231 | if (device->pending_bios) | ||
| 232 | goto loop_lock; | ||
| 233 | spin_unlock(&device->io_lock); | ||
| 232 | done: | 234 | done: |
| 233 | return 0; | 235 | return 0; |
| 234 | } | 236 | } |
| @@ -345,14 +347,11 @@ error: | |||
| 345 | 347 | ||
| 346 | int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) | 348 | int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) |
| 347 | { | 349 | { |
| 348 | struct list_head *tmp; | 350 | struct btrfs_device *device, *next; |
| 349 | struct list_head *cur; | ||
| 350 | struct btrfs_device *device; | ||
| 351 | 351 | ||
| 352 | mutex_lock(&uuid_mutex); | 352 | mutex_lock(&uuid_mutex); |
| 353 | again: | 353 | again: |
| 354 | list_for_each_safe(cur, tmp, &fs_devices->devices) { | 354 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { |
| 355 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 356 | if (device->in_fs_metadata) | 355 | if (device->in_fs_metadata) |
| 357 | continue; | 356 | continue; |
| 358 | 357 | ||
| @@ -383,14 +382,12 @@ again: | |||
| 383 | 382 | ||
| 384 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | 383 | static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) |
| 385 | { | 384 | { |
| 386 | struct list_head *cur; | ||
| 387 | struct btrfs_device *device; | 385 | struct btrfs_device *device; |
| 388 | 386 | ||
| 389 | if (--fs_devices->opened > 0) | 387 | if (--fs_devices->opened > 0) |
| 390 | return 0; | 388 | return 0; |
| 391 | 389 | ||
| 392 | list_for_each(cur, &fs_devices->devices) { | 390 | list_for_each_entry(device, &fs_devices->devices, dev_list) { |
| 393 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 394 | if (device->bdev) { | 391 | if (device->bdev) { |
| 395 | close_bdev_exclusive(device->bdev, device->mode); | 392 | close_bdev_exclusive(device->bdev, device->mode); |
| 396 | fs_devices->open_devices--; | 393 | fs_devices->open_devices--; |
| @@ -439,7 +436,6 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
| 439 | { | 436 | { |
| 440 | struct block_device *bdev; | 437 | struct block_device *bdev; |
| 441 | struct list_head *head = &fs_devices->devices; | 438 | struct list_head *head = &fs_devices->devices; |
| 442 | struct list_head *cur; | ||
| 443 | struct btrfs_device *device; | 439 | struct btrfs_device *device; |
| 444 | struct block_device *latest_bdev = NULL; | 440 | struct block_device *latest_bdev = NULL; |
| 445 | struct buffer_head *bh; | 441 | struct buffer_head *bh; |
| @@ -450,8 +446,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
| 450 | int seeding = 1; | 446 | int seeding = 1; |
| 451 | int ret = 0; | 447 | int ret = 0; |
| 452 | 448 | ||
| 453 | list_for_each(cur, head) { | 449 | list_for_each_entry(device, head, dev_list) { |
| 454 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 455 | if (device->bdev) | 450 | if (device->bdev) |
| 456 | continue; | 451 | continue; |
| 457 | if (!device->name) | 452 | if (!device->name) |
| @@ -578,7 +573,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
| 578 | *(unsigned long long *)disk_super->fsid, | 573 | *(unsigned long long *)disk_super->fsid, |
| 579 | *(unsigned long long *)(disk_super->fsid + 8)); | 574 | *(unsigned long long *)(disk_super->fsid + 8)); |
| 580 | } | 575 | } |
| 581 | printk(KERN_INFO "devid %llu transid %llu %s\n", | 576 | printk(KERN_CONT "devid %llu transid %llu %s\n", |
| 582 | (unsigned long long)devid, (unsigned long long)transid, path); | 577 | (unsigned long long)devid, (unsigned long long)transid, path); |
| 583 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); | 578 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); |
| 584 | 579 | ||
| @@ -1017,14 +1012,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
| 1017 | } | 1012 | } |
| 1018 | 1013 | ||
| 1019 | if (strcmp(device_path, "missing") == 0) { | 1014 | if (strcmp(device_path, "missing") == 0) { |
| 1020 | struct list_head *cur; | ||
| 1021 | struct list_head *devices; | 1015 | struct list_head *devices; |
| 1022 | struct btrfs_device *tmp; | 1016 | struct btrfs_device *tmp; |
| 1023 | 1017 | ||
| 1024 | device = NULL; | 1018 | device = NULL; |
| 1025 | devices = &root->fs_info->fs_devices->devices; | 1019 | devices = &root->fs_info->fs_devices->devices; |
| 1026 | list_for_each(cur, devices) { | 1020 | list_for_each_entry(tmp, devices, dev_list) { |
| 1027 | tmp = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1028 | if (tmp->in_fs_metadata && !tmp->bdev) { | 1021 | if (tmp->in_fs_metadata && !tmp->bdev) { |
| 1029 | device = tmp; | 1022 | device = tmp; |
| 1030 | break; | 1023 | break; |
| @@ -1280,7 +1273,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1280 | struct btrfs_trans_handle *trans; | 1273 | struct btrfs_trans_handle *trans; |
| 1281 | struct btrfs_device *device; | 1274 | struct btrfs_device *device; |
| 1282 | struct block_device *bdev; | 1275 | struct block_device *bdev; |
| 1283 | struct list_head *cur; | ||
| 1284 | struct list_head *devices; | 1276 | struct list_head *devices; |
| 1285 | struct super_block *sb = root->fs_info->sb; | 1277 | struct super_block *sb = root->fs_info->sb; |
| 1286 | u64 total_bytes; | 1278 | u64 total_bytes; |
| @@ -1304,8 +1296,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1304 | mutex_lock(&root->fs_info->volume_mutex); | 1296 | mutex_lock(&root->fs_info->volume_mutex); |
| 1305 | 1297 | ||
| 1306 | devices = &root->fs_info->fs_devices->devices; | 1298 | devices = &root->fs_info->fs_devices->devices; |
| 1307 | list_for_each(cur, devices) { | 1299 | list_for_each_entry(device, devices, dev_list) { |
| 1308 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1309 | if (device->bdev == bdev) { | 1300 | if (device->bdev == bdev) { |
| 1310 | ret = -EEXIST; | 1301 | ret = -EEXIST; |
| 1311 | goto error; | 1302 | goto error; |
| @@ -1704,7 +1695,6 @@ static u64 div_factor(u64 num, int factor) | |||
| 1704 | int btrfs_balance(struct btrfs_root *dev_root) | 1695 | int btrfs_balance(struct btrfs_root *dev_root) |
| 1705 | { | 1696 | { |
| 1706 | int ret; | 1697 | int ret; |
| 1707 | struct list_head *cur; | ||
| 1708 | struct list_head *devices = &dev_root->fs_info->fs_devices->devices; | 1698 | struct list_head *devices = &dev_root->fs_info->fs_devices->devices; |
| 1709 | struct btrfs_device *device; | 1699 | struct btrfs_device *device; |
| 1710 | u64 old_size; | 1700 | u64 old_size; |
| @@ -1723,8 +1713,7 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
| 1723 | dev_root = dev_root->fs_info->dev_root; | 1713 | dev_root = dev_root->fs_info->dev_root; |
| 1724 | 1714 | ||
| 1725 | /* step one make some room on all the devices */ | 1715 | /* step one make some room on all the devices */ |
| 1726 | list_for_each(cur, devices) { | 1716 | list_for_each_entry(device, devices, dev_list) { |
| 1727 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
| 1728 | old_size = device->total_bytes; | 1717 | old_size = device->total_bytes; |
| 1729 | size_to_free = div_factor(old_size, 1); | 1718 | size_to_free = div_factor(old_size, 1); |
| 1730 | size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); | 1719 | size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); |
| @@ -2905,10 +2894,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | |||
| 2905 | free_extent_map(em); | 2894 | free_extent_map(em); |
| 2906 | } | 2895 | } |
| 2907 | 2896 | ||
| 2908 | map = kzalloc(sizeof(*map), GFP_NOFS); | ||
| 2909 | if (!map) | ||
| 2910 | return -ENOMEM; | ||
| 2911 | |||
| 2912 | em = alloc_extent_map(GFP_NOFS); | 2897 | em = alloc_extent_map(GFP_NOFS); |
| 2913 | if (!em) | 2898 | if (!em) |
| 2914 | return -ENOMEM; | 2899 | return -ENOMEM; |
| @@ -3117,6 +3102,8 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
| 3117 | if (!sb) | 3102 | if (!sb) |
| 3118 | return -ENOMEM; | 3103 | return -ENOMEM; |
| 3119 | btrfs_set_buffer_uptodate(sb); | 3104 | btrfs_set_buffer_uptodate(sb); |
| 3105 | btrfs_set_buffer_lockdep_class(sb, 0); | ||
| 3106 | |||
| 3120 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); | 3107 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); |
| 3121 | array_size = btrfs_super_sys_array_size(super_copy); | 3108 | array_size = btrfs_super_sys_array_size(super_copy); |
| 3122 | 3109 | ||
