aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2013-08-23 06:20:17 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:16:04 -0400
commit12bd2fc0d2f589f9605b8f497eee2e7724f3af24 (patch)
treedf82467f721c91a82db67d6820dadb6815078648 /fs/btrfs/volumes.c
parent53f10659f9994df8efe788f82d3da78d48e650c5 (diff)
Btrfs: add btrfs_alloc_device and switch to it
Currently btrfs_device is allocated ad-hoc in a few different places, and as a result not all fields are initialized properly. In particular, readahead state is only initialized in device_list_add (at scan time), and not in btrfs_init_new_device (when the new device is added with 'btrfs dev add'). Fix this by adding an allocation helper and switch everybody but __btrfs_close_devices to it. (__btrfs_close_devices is dealt with in a later commit.) Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c151
1 files changed, 94 insertions, 57 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 9b3595e370f8..4bc07d910e54 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -102,6 +102,27 @@ void btrfs_cleanup_fs_uuids(void)
102 } 102 }
103} 103}
104 104
105static struct btrfs_device *__alloc_device(void)
106{
107 struct btrfs_device *dev;
108
109 dev = kzalloc(sizeof(*dev), GFP_NOFS);
110 if (!dev)
111 return ERR_PTR(-ENOMEM);
112
113 INIT_LIST_HEAD(&dev->dev_list);
114 INIT_LIST_HEAD(&dev->dev_alloc_list);
115
116 spin_lock_init(&dev->io_lock);
117
118 spin_lock_init(&dev->reada_lock);
119 atomic_set(&dev->reada_in_flight, 0);
120 INIT_RADIX_TREE(&dev->reada_zones, GFP_NOFS & ~__GFP_WAIT);
121 INIT_RADIX_TREE(&dev->reada_extents, GFP_NOFS & ~__GFP_WAIT);
122
123 return dev;
124}
125
105static noinline struct btrfs_device *__find_device(struct list_head *head, 126static noinline struct btrfs_device *__find_device(struct list_head *head,
106 u64 devid, u8 *uuid) 127 u64 devid, u8 *uuid)
107{ 128{
@@ -415,17 +436,12 @@ static noinline int device_list_add(const char *path,
415 if (fs_devices->opened) 436 if (fs_devices->opened)
416 return -EBUSY; 437 return -EBUSY;
417 438
418 device = kzalloc(sizeof(*device), GFP_NOFS); 439 device = btrfs_alloc_device(NULL, &devid,
419 if (!device) { 440 disk_super->dev_item.uuid);
441 if (IS_ERR(device)) {
420 /* we can safely leave the fs_devices entry around */ 442 /* we can safely leave the fs_devices entry around */
421 return -ENOMEM; 443 return PTR_ERR(device);
422 } 444 }
423 device->devid = devid;
424 device->dev_stats_valid = 0;
425 device->work.func = pending_bios_fn;
426 memcpy(device->uuid, disk_super->dev_item.uuid,
427 BTRFS_UUID_SIZE);
428 spin_lock_init(&device->io_lock);
429 445
430 name = rcu_string_strdup(path, GFP_NOFS); 446 name = rcu_string_strdup(path, GFP_NOFS);
431 if (!name) { 447 if (!name) {
@@ -433,15 +449,6 @@ static noinline int device_list_add(const char *path,
433 return -ENOMEM; 449 return -ENOMEM;
434 } 450 }
435 rcu_assign_pointer(device->name, name); 451 rcu_assign_pointer(device->name, name);
436 INIT_LIST_HEAD(&device->dev_alloc_list);
437
438 /* init readahead state */
439 spin_lock_init(&device->reada_lock);
440 device->reada_curr_zone = NULL;
441 atomic_set(&device->reada_in_flight, 0);
442 device->reada_next = 0;
443 INIT_RADIX_TREE(&device->reada_zones, GFP_NOFS & ~__GFP_WAIT);
444 INIT_RADIX_TREE(&device->reada_extents, GFP_NOFS & ~__GFP_WAIT);
445 452
446 mutex_lock(&fs_devices->device_list_mutex); 453 mutex_lock(&fs_devices->device_list_mutex);
447 list_add_rcu(&device->dev_list, &fs_devices->devices); 454 list_add_rcu(&device->dev_list, &fs_devices->devices);
@@ -492,8 +499,9 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
492 list_for_each_entry(orig_dev, &orig->devices, dev_list) { 499 list_for_each_entry(orig_dev, &orig->devices, dev_list) {
493 struct rcu_string *name; 500 struct rcu_string *name;
494 501
495 device = kzalloc(sizeof(*device), GFP_NOFS); 502 device = btrfs_alloc_device(NULL, &orig_dev->devid,
496 if (!device) 503 orig_dev->uuid);
504 if (IS_ERR(device))
497 goto error; 505 goto error;
498 506
499 /* 507 /*
@@ -507,13 +515,6 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
507 } 515 }
508 rcu_assign_pointer(device->name, name); 516 rcu_assign_pointer(device->name, name);
509 517
510 device->devid = orig_dev->devid;
511 device->work.func = pending_bios_fn;
512 memcpy(device->uuid, orig_dev->uuid, sizeof(device->uuid));
513 spin_lock_init(&device->io_lock);
514 INIT_LIST_HEAD(&device->dev_list);
515 INIT_LIST_HEAD(&device->dev_alloc_list);
516
517 list_add(&device->dev_list, &fs_devices->devices); 518 list_add(&device->dev_list, &fs_devices->devices);
518 device->fs_devices = fs_devices; 519 device->fs_devices = fs_devices;
519 fs_devices->num_devices++; 520 fs_devices->num_devices++;
@@ -1959,10 +1960,10 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1959 } 1960 }
1960 mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); 1961 mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
1961 1962
1962 device = kzalloc(sizeof(*device), GFP_NOFS); 1963 device = btrfs_alloc_device(root->fs_info, NULL, NULL);
1963 if (!device) { 1964 if (IS_ERR(device)) {
1964 /* we can safely leave the fs_devices entry around */ 1965 /* we can safely leave the fs_devices entry around */
1965 ret = -ENOMEM; 1966 ret = PTR_ERR(device);
1966 goto error; 1967 goto error;
1967 } 1968 }
1968 1969
@@ -1974,13 +1975,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1974 } 1975 }
1975 rcu_assign_pointer(device->name, name); 1976 rcu_assign_pointer(device->name, name);
1976 1977
1977 ret = find_next_devid(root->fs_info, &device->devid);
1978 if (ret) {
1979 rcu_string_free(device->name);
1980 kfree(device);
1981 goto error;
1982 }
1983
1984 trans = btrfs_start_transaction(root, 0); 1978 trans = btrfs_start_transaction(root, 0);
1985 if (IS_ERR(trans)) { 1979 if (IS_ERR(trans)) {
1986 rcu_string_free(device->name); 1980 rcu_string_free(device->name);
@@ -1995,9 +1989,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1995 if (blk_queue_discard(q)) 1989 if (blk_queue_discard(q))
1996 device->can_discard = 1; 1990 device->can_discard = 1;
1997 device->writeable = 1; 1991 device->writeable = 1;
1998 device->work.func = pending_bios_fn;
1999 generate_random_uuid(device->uuid);
2000 spin_lock_init(&device->io_lock);
2001 device->generation = trans->transid; 1992 device->generation = trans->transid;
2002 device->io_width = root->sectorsize; 1993 device->io_width = root->sectorsize;
2003 device->io_align = root->sectorsize; 1994 device->io_align = root->sectorsize;
@@ -2124,6 +2115,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path,
2124 struct btrfs_fs_info *fs_info = root->fs_info; 2115 struct btrfs_fs_info *fs_info = root->fs_info;
2125 struct list_head *devices; 2116 struct list_head *devices;
2126 struct rcu_string *name; 2117 struct rcu_string *name;
2118 u64 devid = BTRFS_DEV_REPLACE_DEVID;
2127 int ret = 0; 2119 int ret = 0;
2128 2120
2129 *device_out = NULL; 2121 *device_out = NULL;
@@ -2145,9 +2137,9 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path,
2145 } 2137 }
2146 } 2138 }
2147 2139
2148 device = kzalloc(sizeof(*device), GFP_NOFS); 2140 device = btrfs_alloc_device(NULL, &devid, NULL);
2149 if (!device) { 2141 if (IS_ERR(device)) {
2150 ret = -ENOMEM; 2142 ret = PTR_ERR(device);
2151 goto error; 2143 goto error;
2152 } 2144 }
2153 2145
@@ -2164,10 +2156,6 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path,
2164 device->can_discard = 1; 2156 device->can_discard = 1;
2165 mutex_lock(&root->fs_info->fs_devices->device_list_mutex); 2157 mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
2166 device->writeable = 1; 2158 device->writeable = 1;
2167 device->work.func = pending_bios_fn;
2168 generate_random_uuid(device->uuid);
2169 device->devid = BTRFS_DEV_REPLACE_DEVID;
2170 spin_lock_init(&device->io_lock);
2171 device->generation = 0; 2159 device->generation = 0;
2172 device->io_width = root->sectorsize; 2160 device->io_width = root->sectorsize;
2173 device->io_align = root->sectorsize; 2161 device->io_align = root->sectorsize;
@@ -5572,23 +5560,72 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root,
5572 struct btrfs_device *device; 5560 struct btrfs_device *device;
5573 struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; 5561 struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
5574 5562
5575 device = kzalloc(sizeof(*device), GFP_NOFS); 5563 device = btrfs_alloc_device(NULL, &devid, dev_uuid);
5576 if (!device) 5564 if (IS_ERR(device))
5577 return NULL; 5565 return NULL;
5578 list_add(&device->dev_list, 5566
5579 &fs_devices->devices); 5567 list_add(&device->dev_list, &fs_devices->devices);
5580 device->devid = devid;
5581 device->work.func = pending_bios_fn;
5582 device->fs_devices = fs_devices; 5568 device->fs_devices = fs_devices;
5583 device->missing = 1;
5584 fs_devices->num_devices++; 5569 fs_devices->num_devices++;
5570
5571 device->missing = 1;
5585 fs_devices->missing_devices++; 5572 fs_devices->missing_devices++;
5586 spin_lock_init(&device->io_lock); 5573
5587 INIT_LIST_HEAD(&device->dev_alloc_list);
5588 memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE);
5589 return device; 5574 return device;
5590} 5575}
5591 5576
5577/**
5578 * btrfs_alloc_device - allocate struct btrfs_device
5579 * @fs_info: used only for generating a new devid, can be NULL if
5580 * devid is provided (i.e. @devid != NULL).
5581 * @devid: a pointer to devid for this device. If NULL a new devid
5582 * is generated.
5583 * @uuid: a pointer to UUID for this device. If NULL a new UUID
5584 * is generated.
5585 *
5586 * Return: a pointer to a new &struct btrfs_device on success; ERR_PTR()
5587 * on error. Returned struct is not linked onto any lists and can be
5588 * destroyed with kfree() right away.
5589 */
5590struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
5591 const u64 *devid,
5592 const u8 *uuid)
5593{
5594 struct btrfs_device *dev;
5595 u64 tmp;
5596
5597 if (!devid && !fs_info) {
5598 WARN_ON(1);
5599 return ERR_PTR(-EINVAL);
5600 }
5601
5602 dev = __alloc_device();
5603 if (IS_ERR(dev))
5604 return dev;
5605
5606 if (devid)
5607 tmp = *devid;
5608 else {
5609 int ret;
5610
5611 ret = find_next_devid(fs_info, &tmp);
5612 if (ret) {
5613 kfree(dev);
5614 return ERR_PTR(ret);
5615 }
5616 }
5617 dev->devid = tmp;
5618
5619 if (uuid)
5620 memcpy(dev->uuid, uuid, BTRFS_UUID_SIZE);
5621 else
5622 generate_random_uuid(dev->uuid);
5623
5624 dev->work.func = pending_bios_fn;
5625
5626 return dev;
5627}
5628
5592static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, 5629static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
5593 struct extent_buffer *leaf, 5630 struct extent_buffer *leaf,
5594 struct btrfs_chunk *chunk) 5631 struct btrfs_chunk *chunk)