aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Jain <anand.jain@oracle.com>2015-08-14 06:33:05 -0400
committerDavid Sterba <dsterba@suse.com>2015-10-01 12:00:05 -0400
commitf190aa471a7a703444f6587ed79c24a04a22d848 (patch)
tree8c99d30f1758dc6fbe119e861678be511caf03b3
parent097efc966ab3e2c3677698f4ab5b229bfff101dd (diff)
Btrfs: add helper for closing one device
Signed-off-by: Anand Jain <anand.jain@oracle.com> [reworded subject and changelog] Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/volumes.c66
-rw-r--r--fs/btrfs/volumes.h1
2 files changed, 37 insertions, 30 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 694d82bccb0b..5688b7821b3d 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -764,36 +764,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
764 764
765 mutex_lock(&fs_devices->device_list_mutex); 765 mutex_lock(&fs_devices->device_list_mutex);
766 list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) { 766 list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
767 struct btrfs_device *new_device; 767 btrfs_close_one_device(device);
768 struct rcu_string *name;
769
770 if (device->bdev)
771 fs_devices->open_devices--;
772
773 if (device->writeable &&
774 device->devid != BTRFS_DEV_REPLACE_DEVID) {
775 list_del_init(&device->dev_alloc_list);
776 fs_devices->rw_devices--;
777 }
778
779 if (device->missing)
780 fs_devices->missing_devices--;
781
782 new_device = btrfs_alloc_device(NULL, &device->devid,
783 device->uuid);
784 BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
785
786 /* Safe because we are under uuid_mutex */
787 if (device->name) {
788 name = rcu_string_strdup(device->name->str, GFP_NOFS);
789 BUG_ON(!name); /* -ENOMEM */
790 rcu_assign_pointer(new_device->name, name);
791 }
792
793 list_replace_rcu(&device->dev_list, &new_device->dev_list);
794 new_device->fs_devices = device->fs_devices;
795
796 call_rcu(&device->rcu, free_device);
797 } 768 }
798 mutex_unlock(&fs_devices->device_list_mutex); 769 mutex_unlock(&fs_devices->device_list_mutex);
799 770
@@ -6834,3 +6805,38 @@ void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info)
6834 fs_devices = fs_devices->seed; 6805 fs_devices = fs_devices->seed;
6835 } 6806 }
6836} 6807}
6808
6809void btrfs_close_one_device(struct btrfs_device *device)
6810{
6811 struct btrfs_fs_devices *fs_devices = device->fs_devices;
6812 struct btrfs_device *new_device;
6813 struct rcu_string *name;
6814
6815 if (device->bdev)
6816 fs_devices->open_devices--;
6817
6818 if (device->writeable &&
6819 device->devid != BTRFS_DEV_REPLACE_DEVID) {
6820 list_del_init(&device->dev_alloc_list);
6821 fs_devices->rw_devices--;
6822 }
6823
6824 if (device->missing)
6825 fs_devices->missing_devices--;
6826
6827 new_device = btrfs_alloc_device(NULL, &device->devid,
6828 device->uuid);
6829 BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
6830
6831 /* Safe because we are under uuid_mutex */
6832 if (device->name) {
6833 name = rcu_string_strdup(device->name->str, GFP_NOFS);
6834 BUG_ON(!name); /* -ENOMEM */
6835 rcu_assign_pointer(new_device->name, name);
6836 }
6837
6838 list_replace_rcu(&device->dev_list, &new_device->dev_list);
6839 new_device->fs_devices = device->fs_devices;
6840
6841 call_rcu(&device->rcu, free_device);
6842}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 8663bf7c5051..38450dc28837 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -547,5 +547,6 @@ static inline void unlock_chunks(struct btrfs_root *root)
547struct list_head *btrfs_get_fs_uuids(void); 547struct list_head *btrfs_get_fs_uuids(void);
548void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info); 548void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info);
549void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info); 549void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info);
550void btrfs_close_one_device(struct btrfs_device *device);
550 551
551#endif 552#endif