diff options
Diffstat (limited to 'drivers/target/target_core_device.c')
-rw-r--r-- | drivers/target/target_core_device.c | 53 |
1 files changed, 20 insertions, 33 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index e27db4d45a9d..47b5ef153135 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -336,7 +336,6 @@ int core_enable_device_list_for_node( return -ENOMEM; } - atomic_set(&new->ua_count, 0); spin_lock_init(&new->ua_lock); INIT_LIST_HEAD(&new->ua_list); INIT_LIST_HEAD(&new->lun_link); @@ -879,39 +878,21 @@ sector_t target_to_linux_sector(struct se_device *dev, sector_t lb) } EXPORT_SYMBOL(target_to_linux_sector); -/** - * target_find_device - find a se_device by its dev_index - * @id: dev_index - * @do_depend: true if caller needs target_depend_item to be done - * - * If do_depend is true, the caller must do a target_undepend_item - * when finished using the device. - * - * If do_depend is false, the caller must be called in a configfs - * callback or during removal. - */ -struct se_device *target_find_device(int id, bool do_depend) -{ - struct se_device *dev; - - mutex_lock(&device_mutex); - dev = idr_find(&devices_idr, id); - if (dev && do_depend && target_depend_item(&dev->dev_group.cg_item)) - dev = NULL; - mutex_unlock(&device_mutex); - return dev; -} -EXPORT_SYMBOL(target_find_device); - struct devices_idr_iter { + struct config_item *prev_item; int (*fn)(struct se_device *dev, void *data); void *data; }; static int target_devices_idr_iter(int id, void *p, void *data) + __must_hold(&device_mutex) { struct devices_idr_iter *iter = data; struct se_device *dev = p; + int ret; + + config_item_put(iter->prev_item); + iter->prev_item = NULL; /* * We add the device early to the idr, so it can be used @@ -919,10 +900,18 @@ static int target_devices_idr_iter(int id, void *p, void *data) * to allow other callers to access partially setup devices, * so we skip them here. */ - if (!(dev->dev_flags & DF_CONFIGURED)) + if (!target_dev_configured(dev)) + return 0; + + iter->prev_item = config_item_get_unless_zero(&dev->dev_group.cg_item); + if (!iter->prev_item) return 0; + mutex_unlock(&device_mutex); + + ret = iter->fn(dev, iter->data); - return iter->fn(dev, iter->data); + mutex_lock(&device_mutex); + return ret; } /** @@ -936,15 +925,13 @@ static int target_devices_idr_iter(int id, void *p, void *data) int target_for_each_device(int (*fn)(struct se_device *dev, void *data), void *data) { - struct devices_idr_iter iter; + struct devices_idr_iter iter = { .fn = fn, .data = data }; int ret; - iter.fn = fn; - iter.data = data; - mutex_lock(&device_mutex); ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter); mutex_unlock(&device_mutex); + config_item_put(iter.prev_item); return ret; } @@ -953,7 +940,7 @@ int target_configure_device(struct se_device *dev) struct se_hba *hba = dev->se_hba; int ret, id; - if (dev->dev_flags & DF_CONFIGURED) { + if (target_dev_configured(dev)) { pr_err("se_dev->se_dev_ptr already set for storage" " object\n"); return -EEXIST; @@ -1058,7 +1045,7 @@ void target_free_device(struct se_device *dev) WARN_ON(!list_empty(&dev->dev_sep_list)); - if (dev->dev_flags & DF_CONFIGURED) { + if (target_dev_configured(dev)) { destroy_workqueue(dev->tmr_wq); dev->transport->destroy_device(dev); |