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.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 91851b555e2e..177b73179590 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -413,12 +413,16 @@ static noinline int device_list_add(const char *path,
413 413
414 device->fs_devices = fs_devices; 414 device->fs_devices = fs_devices;
415 fs_devices->num_devices++; 415 fs_devices->num_devices++;
416 } else if (strcmp(device->name, path)) { 416 } else if (!device->name || strcmp(device->name, path)) {
417 name = kstrdup(path, GFP_NOFS); 417 name = kstrdup(path, GFP_NOFS);
418 if (!name) 418 if (!name)
419 return -ENOMEM; 419 return -ENOMEM;
420 kfree(device->name); 420 kfree(device->name);
421 device->name = name; 421 device->name = name;
422 if (device->missing) {
423 fs_devices->missing_devices--;
424 device->missing = 0;
425 }
422 } 426 }
423 427
424 if (found_transid > fs_devices->latest_trans) { 428 if (found_transid > fs_devices->latest_trans) {
@@ -1238,6 +1242,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1238 1242
1239 device->fs_devices->num_devices--; 1243 device->fs_devices->num_devices--;
1240 1244
1245 if (device->missing)
1246 root->fs_info->fs_devices->missing_devices--;
1247
1241 next_device = list_entry(root->fs_info->fs_devices->devices.next, 1248 next_device = list_entry(root->fs_info->fs_devices->devices.next,
1242 struct btrfs_device, dev_list); 1249 struct btrfs_device, dev_list);
1243 if (device->bdev == root->fs_info->sb->s_bdev) 1250 if (device->bdev == root->fs_info->sb->s_bdev)
@@ -3084,7 +3091,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root,
3084 device->devid = devid; 3091 device->devid = devid;
3085 device->work.func = pending_bios_fn; 3092 device->work.func = pending_bios_fn;
3086 device->fs_devices = fs_devices; 3093 device->fs_devices = fs_devices;
3094 device->missing = 1;
3087 fs_devices->num_devices++; 3095 fs_devices->num_devices++;
3096 fs_devices->missing_devices++;
3088 spin_lock_init(&device->io_lock); 3097 spin_lock_init(&device->io_lock);
3089 INIT_LIST_HEAD(&device->dev_alloc_list); 3098 INIT_LIST_HEAD(&device->dev_alloc_list);
3090 memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); 3099 memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE);
@@ -3282,6 +3291,15 @@ static int read_one_dev(struct btrfs_root *root,
3282 device = add_missing_dev(root, devid, dev_uuid); 3291 device = add_missing_dev(root, devid, dev_uuid);
3283 if (!device) 3292 if (!device)
3284 return -ENOMEM; 3293 return -ENOMEM;
3294 } else if (!device->missing) {
3295 /*
3296 * this happens when a device that was properly setup
3297 * in the device info lists suddenly goes bad.
3298 * device->bdev is NULL, and so we have to set
3299 * device->missing to one here
3300 */
3301 root->fs_info->fs_devices->missing_devices++;
3302 device->missing = 1;
3285 } 3303 }
3286 } 3304 }
3287 3305