aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c48
1 files changed, 19 insertions, 29 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b187b537888e..bcd14ebccae1 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
119static noinline struct btrfs_fs_devices *find_fsid(u8 *fsid) 116static 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)
159loop: 154loop:
160 spin_lock(&device->io_lock); 155 spin_lock(&device->io_lock);
161 156
157loop_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
@@ -221,6 +217,8 @@ loop:
221 else 217 else
222 device->pending_bio_tail = tail; 218 device->pending_bio_tail = tail;
223 219
220 device->running_pending = 1;
221
224 spin_unlock(&device->io_lock); 222 spin_unlock(&device->io_lock);
225 btrfs_requeue_work(&device->work); 223 btrfs_requeue_work(&device->work);
226 goto done; 224 goto done;
@@ -228,6 +226,11 @@ loop:
228 } 226 }
229 if (again) 227 if (again)
230 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);
231done: 234done:
232 return 0; 235 return 0;
233} 236}
@@ -344,14 +347,11 @@ error:
344 347
345int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) 348int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices)
346{ 349{
347 struct list_head *tmp; 350 struct btrfs_device *device, *next;
348 struct list_head *cur;
349 struct btrfs_device *device;
350 351
351 mutex_lock(&uuid_mutex); 352 mutex_lock(&uuid_mutex);
352again: 353again:
353 list_for_each_safe(cur, tmp, &fs_devices->devices) { 354 list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) {
354 device = list_entry(cur, struct btrfs_device, dev_list);
355 if (device->in_fs_metadata) 355 if (device->in_fs_metadata)
356 continue; 356 continue;
357 357
@@ -382,14 +382,12 @@ again:
382 382
383static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) 383static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
384{ 384{
385 struct list_head *cur;
386 struct btrfs_device *device; 385 struct btrfs_device *device;
387 386
388 if (--fs_devices->opened > 0) 387 if (--fs_devices->opened > 0)
389 return 0; 388 return 0;
390 389
391 list_for_each(cur, &fs_devices->devices) { 390 list_for_each_entry(device, &fs_devices->devices, dev_list) {
392 device = list_entry(cur, struct btrfs_device, dev_list);
393 if (device->bdev) { 391 if (device->bdev) {
394 close_bdev_exclusive(device->bdev, device->mode); 392 close_bdev_exclusive(device->bdev, device->mode);
395 fs_devices->open_devices--; 393 fs_devices->open_devices--;
@@ -438,7 +436,6 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
438{ 436{
439 struct block_device *bdev; 437 struct block_device *bdev;
440 struct list_head *head = &fs_devices->devices; 438 struct list_head *head = &fs_devices->devices;
441 struct list_head *cur;
442 struct btrfs_device *device; 439 struct btrfs_device *device;
443 struct block_device *latest_bdev = NULL; 440 struct block_device *latest_bdev = NULL;
444 struct buffer_head *bh; 441 struct buffer_head *bh;
@@ -449,8 +446,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
449 int seeding = 1; 446 int seeding = 1;
450 int ret = 0; 447 int ret = 0;
451 448
452 list_for_each(cur, head) { 449 list_for_each_entry(device, head, dev_list) {
453 device = list_entry(cur, struct btrfs_device, dev_list);
454 if (device->bdev) 450 if (device->bdev)
455 continue; 451 continue;
456 if (!device->name) 452 if (!device->name)
@@ -577,7 +573,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
577 *(unsigned long long *)disk_super->fsid, 573 *(unsigned long long *)disk_super->fsid,
578 *(unsigned long long *)(disk_super->fsid + 8)); 574 *(unsigned long long *)(disk_super->fsid + 8));
579 } 575 }
580 printk(KERN_INFO "devid %llu transid %llu %s\n", 576 printk(KERN_CONT "devid %llu transid %llu %s\n",
581 (unsigned long long)devid, (unsigned long long)transid, path); 577 (unsigned long long)devid, (unsigned long long)transid, path);
582 ret = device_list_add(path, disk_super, devid, fs_devices_ret); 578 ret = device_list_add(path, disk_super, devid, fs_devices_ret);
583 579
@@ -1016,14 +1012,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1016 } 1012 }
1017 1013
1018 if (strcmp(device_path, "missing") == 0) { 1014 if (strcmp(device_path, "missing") == 0) {
1019 struct list_head *cur;
1020 struct list_head *devices; 1015 struct list_head *devices;
1021 struct btrfs_device *tmp; 1016 struct btrfs_device *tmp;
1022 1017
1023 device = NULL; 1018 device = NULL;
1024 devices = &root->fs_info->fs_devices->devices; 1019 devices = &root->fs_info->fs_devices->devices;
1025 list_for_each(cur, devices) { 1020 list_for_each_entry(tmp, devices, dev_list) {
1026 tmp = list_entry(cur, struct btrfs_device, dev_list);
1027 if (tmp->in_fs_metadata && !tmp->bdev) { 1021 if (tmp->in_fs_metadata && !tmp->bdev) {
1028 device = tmp; 1022 device = tmp;
1029 break; 1023 break;
@@ -1279,7 +1273,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1279 struct btrfs_trans_handle *trans; 1273 struct btrfs_trans_handle *trans;
1280 struct btrfs_device *device; 1274 struct btrfs_device *device;
1281 struct block_device *bdev; 1275 struct block_device *bdev;
1282 struct list_head *cur;
1283 struct list_head *devices; 1276 struct list_head *devices;
1284 struct super_block *sb = root->fs_info->sb; 1277 struct super_block *sb = root->fs_info->sb;
1285 u64 total_bytes; 1278 u64 total_bytes;
@@ -1303,8 +1296,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1303 mutex_lock(&root->fs_info->volume_mutex); 1296 mutex_lock(&root->fs_info->volume_mutex);
1304 1297
1305 devices = &root->fs_info->fs_devices->devices; 1298 devices = &root->fs_info->fs_devices->devices;
1306 list_for_each(cur, devices) { 1299 list_for_each_entry(device, devices, dev_list) {
1307 device = list_entry(cur, struct btrfs_device, dev_list);
1308 if (device->bdev == bdev) { 1300 if (device->bdev == bdev) {
1309 ret = -EEXIST; 1301 ret = -EEXIST;
1310 goto error; 1302 goto error;
@@ -1703,7 +1695,6 @@ static u64 div_factor(u64 num, int factor)
1703int btrfs_balance(struct btrfs_root *dev_root) 1695int btrfs_balance(struct btrfs_root *dev_root)
1704{ 1696{
1705 int ret; 1697 int ret;
1706 struct list_head *cur;
1707 struct list_head *devices = &dev_root->fs_info->fs_devices->devices; 1698 struct list_head *devices = &dev_root->fs_info->fs_devices->devices;
1708 struct btrfs_device *device; 1699 struct btrfs_device *device;
1709 u64 old_size; 1700 u64 old_size;
@@ -1722,8 +1713,7 @@ int btrfs_balance(struct btrfs_root *dev_root)
1722 dev_root = dev_root->fs_info->dev_root; 1713 dev_root = dev_root->fs_info->dev_root;
1723 1714
1724 /* step one make some room on all the devices */ 1715 /* step one make some room on all the devices */
1725 list_for_each(cur, devices) { 1716 list_for_each_entry(device, devices, dev_list) {
1726 device = list_entry(cur, struct btrfs_device, dev_list);
1727 old_size = device->total_bytes; 1717 old_size = device->total_bytes;
1728 size_to_free = div_factor(old_size, 1); 1718 size_to_free = div_factor(old_size, 1);
1729 size_to_free = min(size_to_free, (u64)1 * 1024 * 1024); 1719 size_to_free = min(size_to_free, (u64)1 * 1024 * 1024);