diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-22 09:22:07 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | b30757178dad19a0388d958ff9eea66e674d39ed (patch) | |
tree | de2ff27889daaa15180d49d3d04474cc8ee1f927 /fs/btrfs/volumes.c | |
parent | 3c12ac7205d4bd679fefa722aa9b61385e4b4749 (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.c | 15 |
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 | } |