diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index c83b24251e53..6104676857f5 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "rcu-string.h" | 40 | #include "rcu-string.h" |
41 | #include "math.h" | 41 | #include "math.h" |
42 | #include "dev-replace.h" | 42 | #include "dev-replace.h" |
43 | #include "sysfs.h" | ||
43 | 44 | ||
44 | static int init_first_rw_device(struct btrfs_trans_handle *trans, | 45 | static int init_first_rw_device(struct btrfs_trans_handle *trans, |
45 | struct btrfs_root *root, | 46 | struct btrfs_root *root, |
@@ -554,12 +555,14 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig) | |||
554 | * This is ok to do without rcu read locked because we hold the | 555 | * This is ok to do without rcu read locked because we hold the |
555 | * uuid mutex so nothing we touch in here is going to disappear. | 556 | * uuid mutex so nothing we touch in here is going to disappear. |
556 | */ | 557 | */ |
557 | name = rcu_string_strdup(orig_dev->name->str, GFP_NOFS); | 558 | if (orig_dev->name) { |
558 | if (!name) { | 559 | name = rcu_string_strdup(orig_dev->name->str, GFP_NOFS); |
559 | kfree(device); | 560 | if (!name) { |
560 | goto error; | 561 | kfree(device); |
562 | goto error; | ||
563 | } | ||
564 | rcu_assign_pointer(device->name, name); | ||
561 | } | 565 | } |
562 | rcu_assign_pointer(device->name, name); | ||
563 | 566 | ||
564 | list_add(&device->dev_list, &fs_devices->devices); | 567 | list_add(&device->dev_list, &fs_devices->devices); |
565 | device->fs_devices = fs_devices; | 568 | device->fs_devices = fs_devices; |
@@ -1680,6 +1683,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1680 | if (device->bdev) | 1683 | if (device->bdev) |
1681 | device->fs_devices->open_devices--; | 1684 | device->fs_devices->open_devices--; |
1682 | 1685 | ||
1686 | /* remove sysfs entry */ | ||
1687 | btrfs_kobj_rm_device(root->fs_info, device); | ||
1688 | |||
1683 | call_rcu(&device->rcu, free_device); | 1689 | call_rcu(&device->rcu, free_device); |
1684 | 1690 | ||
1685 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; | 1691 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; |
@@ -2143,9 +2149,14 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
2143 | total_bytes = btrfs_super_num_devices(root->fs_info->super_copy); | 2149 | total_bytes = btrfs_super_num_devices(root->fs_info->super_copy); |
2144 | btrfs_set_super_num_devices(root->fs_info->super_copy, | 2150 | btrfs_set_super_num_devices(root->fs_info->super_copy, |
2145 | total_bytes + 1); | 2151 | total_bytes + 1); |
2152 | |||
2153 | /* add sysfs device entry */ | ||
2154 | btrfs_kobj_add_device(root->fs_info, device); | ||
2155 | |||
2146 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | 2156 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); |
2147 | 2157 | ||
2148 | if (seeding_dev) { | 2158 | if (seeding_dev) { |
2159 | char fsid_buf[BTRFS_UUID_UNPARSED_SIZE]; | ||
2149 | ret = init_first_rw_device(trans, root, device); | 2160 | ret = init_first_rw_device(trans, root, device); |
2150 | if (ret) { | 2161 | if (ret) { |
2151 | btrfs_abort_transaction(trans, root, ret); | 2162 | btrfs_abort_transaction(trans, root, ret); |
@@ -2156,6 +2167,14 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
2156 | btrfs_abort_transaction(trans, root, ret); | 2167 | btrfs_abort_transaction(trans, root, ret); |
2157 | goto error_trans; | 2168 | goto error_trans; |
2158 | } | 2169 | } |
2170 | |||
2171 | /* Sprouting would change fsid of the mounted root, | ||
2172 | * so rename the fsid on the sysfs | ||
2173 | */ | ||
2174 | snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU", | ||
2175 | root->fs_info->fsid); | ||
2176 | if (kobject_rename(&root->fs_info->super_kobj, fsid_buf)) | ||
2177 | goto error_trans; | ||
2159 | } else { | 2178 | } else { |
2160 | ret = btrfs_add_device(trans, root, device); | 2179 | ret = btrfs_add_device(trans, root, device); |
2161 | if (ret) { | 2180 | if (ret) { |
@@ -2205,6 +2224,7 @@ error_trans: | |||
2205 | unlock_chunks(root); | 2224 | unlock_chunks(root); |
2206 | btrfs_end_transaction(trans, root); | 2225 | btrfs_end_transaction(trans, root); |
2207 | rcu_string_free(device->name); | 2226 | rcu_string_free(device->name); |
2227 | btrfs_kobj_rm_device(root->fs_info, device); | ||
2208 | kfree(device); | 2228 | kfree(device); |
2209 | error: | 2229 | error: |
2210 | blkdev_put(bdev, FMODE_EXCL); | 2230 | blkdev_put(bdev, FMODE_EXCL); |