aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-22 09:22:07 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:02 -0400
commitb30757178dad19a0388d958ff9eea66e674d39ed (patch)
treede2ff27889daaa15180d49d3d04474cc8ee1f927 /fs/btrfs/volumes.c
parent3c12ac7205d4bd679fefa722aa9b61385e4b4749 (diff)
Btrfs: Add a special device list for chunk allocations
This allows other code that needs to walk every device in the FS to do so without locking against allocations. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 107fc74c3ab8..5619e50583e3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -111,6 +111,7 @@ static int device_list_add(const char *path,
111 if (!fs_devices) 111 if (!fs_devices)
112 return -ENOMEM; 112 return -ENOMEM;
113 INIT_LIST_HEAD(&fs_devices->devices); 113 INIT_LIST_HEAD(&fs_devices->devices);
114 INIT_LIST_HEAD(&fs_devices->alloc_list);
114 list_add(&fs_devices->list, &fs_uuids); 115 list_add(&fs_devices->list, &fs_uuids);
115 memcpy(fs_devices->fsid, disk_super->fsid, BTRFS_FSID_SIZE); 116 memcpy(fs_devices->fsid, disk_super->fsid, BTRFS_FSID_SIZE);
116 fs_devices->latest_devid = devid; 117 fs_devices->latest_devid = devid;
@@ -139,6 +140,7 @@ static int device_list_add(const char *path,
139 return -ENOMEM; 140 return -ENOMEM;
140 } 141 }
141 list_add(&device->dev_list, &fs_devices->devices); 142 list_add(&device->dev_list, &fs_devices->devices);
143 list_add(&device->dev_alloc_list, &fs_devices->alloc_list);
142 fs_devices->num_devices++; 144 fs_devices->num_devices++;
143 } 145 }
144 146
@@ -660,7 +662,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
660 struct btrfs_device *device = NULL; 662 struct btrfs_device *device = NULL;
661 struct btrfs_chunk *chunk; 663 struct btrfs_chunk *chunk;
662 struct list_head private_devs; 664 struct list_head private_devs;
663 struct list_head *dev_list = &extent_root->fs_info->fs_devices->devices; 665 struct list_head *dev_list;
664 struct list_head *cur; 666 struct list_head *cur;
665 struct extent_map_tree *em_tree; 667 struct extent_map_tree *em_tree;
666 struct map_lookup *map; 668 struct map_lookup *map;
@@ -682,6 +684,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
682 int stripe_len = 64 * 1024; 684 int stripe_len = 64 * 1024;
683 struct btrfs_key key; 685 struct btrfs_key key;
684 686
687 dev_list = &extent_root->fs_info->fs_devices->alloc_list;
685 if (list_empty(dev_list)) 688 if (list_empty(dev_list))
686 return -ENOSPC; 689 return -ENOSPC;
687 690
@@ -752,12 +755,12 @@ again:
752 755
753 /* build a private list of devices we will allocate from */ 756 /* build a private list of devices we will allocate from */
754 while(index < num_stripes) { 757 while(index < num_stripes) {
755 device = list_entry(cur, struct btrfs_device, dev_list); 758 device = list_entry(cur, struct btrfs_device, dev_alloc_list);
756 759
757 avail = device->total_bytes - device->bytes_used; 760 avail = device->total_bytes - device->bytes_used;
758 cur = cur->next; 761 cur = cur->next;
759 if (avail >= min_free) { 762 if (avail >= min_free) {
760 list_move_tail(&device->dev_list, &private_devs); 763 list_move_tail(&device->dev_alloc_list, &private_devs);
761 index++; 764 index++;
762 if (type & BTRFS_BLOCK_GROUP_DUP) 765 if (type & BTRFS_BLOCK_GROUP_DUP)
763 index++; 766 index++;
@@ -812,12 +815,12 @@ printk("new chunk type %Lu start %Lu size %Lu\n", type, key.offset, *num_bytes);
812 struct btrfs_stripe *stripe; 815 struct btrfs_stripe *stripe;
813 BUG_ON(list_empty(&private_devs)); 816 BUG_ON(list_empty(&private_devs));
814 cur = private_devs.next; 817 cur = private_devs.next;
815 device = list_entry(cur, struct btrfs_device, dev_list); 818 device = list_entry(cur, struct btrfs_device, dev_alloc_list);
816 819
817 /* loop over this device again if we're doing a dup group */ 820 /* loop over this device again if we're doing a dup group */
818 if (!(type & BTRFS_BLOCK_GROUP_DUP) || 821 if (!(type & BTRFS_BLOCK_GROUP_DUP) ||
819 (index == num_stripes - 1)) 822 (index == num_stripes - 1))
820 list_move_tail(&device->dev_list, dev_list); 823 list_move_tail(&device->dev_alloc_list, dev_list);
821 824
822 ret = btrfs_alloc_dev_extent(trans, device, 825 ret = btrfs_alloc_dev_extent(trans, device,
823 info->chunk_root->root_key.objectid, 826 info->chunk_root->root_key.objectid,
@@ -1329,6 +1332,8 @@ static int read_one_dev(struct btrfs_root *root,
1329 return -ENOMEM; 1332 return -ENOMEM;
1330 list_add(&device->dev_list, 1333 list_add(&device->dev_list,
1331 &root->fs_info->fs_devices->devices); 1334 &root->fs_info->fs_devices->devices);
1335 list_add(&device->dev_alloc_list,
1336 &root->fs_info->fs_devices->alloc_list);
1332 device->barriers = 1; 1337 device->barriers = 1;
1333 spin_lock_init(&device->io_lock); 1338 spin_lock_init(&device->io_lock);
1334 } 1339 }