Commit f3450c7b authored by Swen Schillig's avatar Swen Schillig Committed by James Bottomley
Browse files

[SCSI] zfcp: Replace local reference counting with common kref



Replace the local reference counting by already available mechanisms
offered by kref. Where possible existing device structures were used,
including the same functionality.

Signed-off-by: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent ecf0c772
Loading
Loading
Loading
Loading
+108 −123
Original line number Original line Diff line number Diff line
@@ -96,13 +96,12 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
	adapter = dev_get_drvdata(&ccwdev->dev);
	adapter = dev_get_drvdata(&ccwdev->dev);
	if (!adapter)
	if (!adapter)
		goto out_unlock;
		goto out_unlock;
	zfcp_adapter_get(adapter);
	kref_get(&adapter->ref);


	port = zfcp_get_port_by_wwpn(adapter, wwpn);
	port = zfcp_get_port_by_wwpn(adapter, wwpn);
	if (!port)
	if (!port)
		goto out_port;
		goto out_port;


	zfcp_port_get(port);
	unit = zfcp_unit_enqueue(port, lun);
	unit = zfcp_unit_enqueue(port, lun);
	if (IS_ERR(unit))
	if (IS_ERR(unit))
		goto out_unit;
		goto out_unit;
@@ -113,11 +112,10 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
	flush_work(&unit->scsi_work);
	flush_work(&unit->scsi_work);


	mutex_lock(&zfcp_data.config_mutex);
	mutex_lock(&zfcp_data.config_mutex);
	zfcp_unit_put(unit);
out_unit:
out_unit:
	zfcp_port_put(port);
	put_device(&port->sysfs_device);
out_port:
out_port:
	zfcp_adapter_put(adapter);
	kref_put(&adapter->ref, zfcp_adapter_release);
out_unlock:
out_unlock:
	mutex_unlock(&zfcp_data.config_mutex);
	mutex_unlock(&zfcp_data.config_mutex);
out_ccwdev:
out_ccwdev:
@@ -244,7 +242,7 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun)
	list_for_each_entry(unit, &port->unit_list, list)
	list_for_each_entry(unit, &port->unit_list, list)
		if ((unit->fcp_lun == fcp_lun) &&
		if ((unit->fcp_lun == fcp_lun) &&
		    !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE)) {
		    !(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_REMOVE)) {
			zfcp_unit_get(unit);
			get_device(&unit->sysfs_device);
			read_unlock_irqrestore(&port->unit_list_lock, flags);
			read_unlock_irqrestore(&port->unit_list_lock, flags);
			return unit;
			return unit;
		}
		}
@@ -269,7 +267,7 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
	list_for_each_entry(port, &adapter->port_list, list)
	list_for_each_entry(port, &adapter->port_list, list)
		if ((port->wwpn == wwpn) &&
		if ((port->wwpn == wwpn) &&
		    !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE)) {
		    !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE)) {
			zfcp_port_get(port);
			get_device(&port->sysfs_device);
			read_unlock_irqrestore(&adapter->port_list_lock, flags);
			read_unlock_irqrestore(&adapter->port_list_lock, flags);
			return port;
			return port;
		}
		}
@@ -277,9 +275,20 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
	return NULL;
	return NULL;
}
}


static void zfcp_sysfs_unit_release(struct device *dev)
/**
 * zfcp_unit_release - dequeue unit
 * @dev: pointer to device
 *
 * waits until all work is done on unit and removes it then from the unit->list
 * of the associated port.
 */
static void zfcp_unit_release(struct device *dev)
{
{
	kfree(container_of(dev, struct zfcp_unit, sysfs_device));
	struct zfcp_unit *unit = container_of(dev, struct zfcp_unit,
					      sysfs_device);

	put_device(&unit->port->sysfs_device);
	kfree(unit);
}
}


/**
/**
@@ -294,36 +303,39 @@ static void zfcp_sysfs_unit_release(struct device *dev)
struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
{
{
	struct zfcp_unit *unit;
	struct zfcp_unit *unit;
	int retval = -ENOMEM;

	get_device(&port->sysfs_device);


	unit = zfcp_get_unit_by_lun(port, fcp_lun);
	unit = zfcp_get_unit_by_lun(port, fcp_lun);
	if (unit) {
	if (unit) {
		zfcp_unit_put(unit);
		put_device(&unit->sysfs_device);
		return ERR_PTR(-EINVAL);
		retval = -EEXIST;
		goto err_out;
	}
	}


	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
	if (!unit)
	if (!unit)
		return ERR_PTR(-ENOMEM);
		goto err_out;

	atomic_set(&unit->refcount, 0);
	init_waitqueue_head(&unit->remove_wq);
	INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);


	unit->port = port;
	unit->port = port;
	unit->fcp_lun = fcp_lun;
	unit->fcp_lun = fcp_lun;
	unit->sysfs_device.parent = &port->sysfs_device;
	unit->sysfs_device.release = zfcp_unit_release;


	if (dev_set_name(&unit->sysfs_device, "0x%016llx",
	if (dev_set_name(&unit->sysfs_device, "0x%016llx",
			 (unsigned long long) fcp_lun)) {
			 (unsigned long long) fcp_lun)) {
		kfree(unit);
		kfree(unit);
		return ERR_PTR(-ENOMEM);
		goto err_out;
	}
	}
	unit->sysfs_device.parent = &port->sysfs_device;
	unit->sysfs_device.release = zfcp_sysfs_unit_release;
	dev_set_drvdata(&unit->sysfs_device, unit);
	dev_set_drvdata(&unit->sysfs_device, unit);
	retval = -EINVAL;


	/* mark unit unusable as long as sysfs registration is not complete */
	/* mark unit unusable as long as sysfs registration is not complete */
	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);


	INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);

	spin_lock_init(&unit->latencies.lock);
	spin_lock_init(&unit->latencies.lock);
	unit->latencies.write.channel.min = 0xFFFFFFFF;
	unit->latencies.write.channel.min = 0xFFFFFFFF;
	unit->latencies.write.fabric.min = 0xFFFFFFFF;
	unit->latencies.write.fabric.min = 0xFFFFFFFF;
@@ -334,16 +346,12 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)


	if (device_register(&unit->sysfs_device)) {
	if (device_register(&unit->sysfs_device)) {
		put_device(&unit->sysfs_device);
		put_device(&unit->sysfs_device);
		return ERR_PTR(-EINVAL);
		goto err_out;
	}
	}


	if (sysfs_create_group(&unit->sysfs_device.kobj,
	if (sysfs_create_group(&unit->sysfs_device.kobj,
			       &zfcp_sysfs_unit_attrs)) {
			       &zfcp_sysfs_unit_attrs))
		device_unregister(&unit->sysfs_device);
		goto err_out_put;
		return ERR_PTR(-EINVAL);
	}

	zfcp_unit_get(unit);


	write_lock_irq(&port->unit_list_lock);
	write_lock_irq(&port->unit_list_lock);
	list_add_tail(&unit->list, &port->unit_list);
	list_add_tail(&unit->list, &port->unit_list);
@@ -352,27 +360,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);


	zfcp_port_get(port);

	return unit;
	return unit;
}

/**
 * zfcp_unit_dequeue - dequeue unit
 * @unit: pointer to zfcp_unit
 *
 * waits until all work is done on unit and removes it then from the unit->list
 * of the associated port.
 */
void zfcp_unit_dequeue(struct zfcp_unit *unit)
{
	struct zfcp_port *port = unit->port;


	wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0);
err_out_put:
	list_del(&unit->list); /* no list locking required */
	zfcp_port_put(port);
	sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs);
	device_unregister(&unit->sysfs_device);
	device_unregister(&unit->sysfs_device);
err_out:
	put_device(&port->sysfs_device);
	return ERR_PTR(retval);
}
}


static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
@@ -518,41 +512,44 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
{
{
	struct zfcp_adapter *adapter;
	struct zfcp_adapter *adapter;


	/*
	if (!get_device(&ccw_device->dev))
	 * Note: It is safe to release the list_lock, as any list changes
		return -ENODEV;
	 * are protected by the config_mutex, which must be held to get here
	 */


	adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
	adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
	if (!adapter)
	if (!adapter) {
		put_device(&ccw_device->dev);
		return -ENOMEM;
		return -ENOMEM;
	}

	kref_init(&adapter->ref);


	ccw_device->handler = NULL;
	ccw_device->handler = NULL;
	adapter->ccw_device = ccw_device;
	adapter->ccw_device = ccw_device;
	atomic_set(&adapter->refcount, 0);

	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
	INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);


	if (zfcp_qdio_setup(adapter))
	if (zfcp_qdio_setup(adapter))
		goto qdio_failed;
		goto failed;


	if (zfcp_allocate_low_mem_buffers(adapter))
	if (zfcp_allocate_low_mem_buffers(adapter))
		goto low_mem_buffers_failed;
		goto failed;


	if (zfcp_reqlist_alloc(adapter))
	if (zfcp_reqlist_alloc(adapter))
		goto low_mem_buffers_failed;
		goto failed;


	if (zfcp_dbf_adapter_register(adapter))
	if (zfcp_dbf_adapter_register(adapter))
		goto debug_register_failed;
		goto failed;


	if (zfcp_setup_adapter_work_queue(adapter))
	if (zfcp_setup_adapter_work_queue(adapter))
		goto work_queue_failed;
		goto failed;


	if (zfcp_fc_gs_setup(adapter))
	if (zfcp_fc_gs_setup(adapter))
		goto generic_services_failed;
		goto failed;


	rwlock_init(&adapter->port_list_lock);
	rwlock_init(&adapter->port_list_lock);
	INIT_LIST_HEAD(&adapter->port_list);
	INIT_LIST_HEAD(&adapter->port_list);


	init_waitqueue_head(&adapter->remove_wq);
	init_waitqueue_head(&adapter->erp_ready_wq);
	init_waitqueue_head(&adapter->erp_ready_wq);
	init_waitqueue_head(&adapter->erp_done_wqh);
	init_waitqueue_head(&adapter->erp_done_wqh);


@@ -565,10 +562,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
	rwlock_init(&adapter->abort_lock);
	rwlock_init(&adapter->abort_lock);


	if (zfcp_erp_thread_setup(adapter))
	if (zfcp_erp_thread_setup(adapter))
		goto erp_thread_failed;
		goto failed;

	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
	INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);


	adapter->service_level.seq_print = zfcp_print_sl;
	adapter->service_level.seq_print = zfcp_print_sl;


@@ -579,54 +573,37 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)


	if (sysfs_create_group(&ccw_device->dev.kobj,
	if (sysfs_create_group(&ccw_device->dev.kobj,
			       &zfcp_sysfs_adapter_attrs))
			       &zfcp_sysfs_adapter_attrs))
		goto sysfs_failed;
		goto failed;


	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);


	if (!zfcp_adapter_scsi_register(adapter))
	if (!zfcp_adapter_scsi_register(adapter))
		return 0;
		return 0;


sysfs_failed:
failed:
	zfcp_erp_thread_kill(adapter);
	kref_put(&adapter->ref, zfcp_adapter_release);
erp_thread_failed:
	zfcp_fc_gs_destroy(adapter);
generic_services_failed:
	zfcp_destroy_adapter_work_queue(adapter);
work_queue_failed:
	zfcp_dbf_adapter_unregister(adapter->dbf);
debug_register_failed:
	dev_set_drvdata(&ccw_device->dev, NULL);
	kfree(adapter->req_list);
low_mem_buffers_failed:
	zfcp_free_low_mem_buffers(adapter);
qdio_failed:
	zfcp_qdio_destroy(adapter->qdio);
	kfree(adapter);
	return -ENOMEM;
	return -ENOMEM;
}
}


/**
/**
 * zfcp_adapter_dequeue - remove the adapter from the resource list
 * zfcp_adapter_release - remove the adapter from the resource list
 * @adapter: pointer to struct zfcp_adapter which should be removed
 * @ref: pointer to struct kref
 * locks:	adapter list write lock is assumed to be held by caller
 * locks:	adapter list write lock is assumed to be held by caller
 */
 */
void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
void zfcp_adapter_release(struct kref *ref)
{
{
	int retval = 0;
	struct zfcp_adapter *adapter = container_of(ref, struct zfcp_adapter,
	unsigned long flags;
						    ref);
	struct ccw_device *ccw_device = adapter->ccw_device;


	cancel_work_sync(&adapter->stat_work);
	cancel_work_sync(&adapter->stat_work);

	zfcp_fc_wka_ports_force_offline(adapter->gs);
	zfcp_fc_wka_ports_force_offline(adapter->gs);
	sysfs_remove_group(&adapter->ccw_device->dev.kobj,
	sysfs_remove_group(&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs);
			   &zfcp_sysfs_adapter_attrs);

	dev_set_drvdata(&adapter->ccw_device->dev, NULL);
	dev_set_drvdata(&ccw_device->dev, NULL);
	/* sanity check: no pending FSF requests */
	spin_lock_irqsave(&adapter->req_list_lock, flags);
	retval = zfcp_reqlist_isempty(adapter);
	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
	if (!retval)
		return;


	dev_set_drvdata(&adapter->ccw_device->dev, NULL);
	zfcp_fc_gs_destroy(adapter);
	zfcp_fc_gs_destroy(adapter);
	zfcp_erp_thread_kill(adapter);
	zfcp_erp_thread_kill(adapter);
	zfcp_destroy_adapter_work_queue(adapter);
	zfcp_destroy_adapter_work_queue(adapter);
@@ -637,11 +614,30 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
	kfree(adapter->fc_stats);
	kfree(adapter->fc_stats);
	kfree(adapter->stats_reset_data);
	kfree(adapter->stats_reset_data);
	kfree(adapter);
	kfree(adapter);
	put_device(&ccw_device->dev);
}

/**
 * zfcp_device_unregister - remove port, unit from system
 * @dev: reference to device which is to be removed
 * @grp: related reference to attribute group
 *
 * Helper function to unregister port, unit from system
 */
void zfcp_device_unregister(struct device *dev,
			    const struct attribute_group *grp)
{
	sysfs_remove_group(&dev->kobj, grp);
	device_unregister(dev);
}
}


static void zfcp_sysfs_port_release(struct device *dev)
static void zfcp_port_release(struct device *dev)
{
{
	kfree(container_of(dev, struct zfcp_port, sysfs_device));
	struct zfcp_port *port = container_of(dev, struct zfcp_port,
					      sysfs_device);

	kref_put(&port->adapter->ref, zfcp_adapter_release);
	kfree(port);
}
}


/**
/**
@@ -661,21 +657,24 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
				     u32 status, u32 d_id)
				     u32 status, u32 d_id)
{
{
	struct zfcp_port *port;
	struct zfcp_port *port;
	int retval = -ENOMEM;

	kref_get(&adapter->ref);


	port = zfcp_get_port_by_wwpn(adapter, wwpn);
	port = zfcp_get_port_by_wwpn(adapter, wwpn);
	if (port) {
	if (port) {
		zfcp_port_put(port);
		put_device(&port->sysfs_device);
		return ERR_PTR(-EEXIST);
		retval = -EEXIST;
		goto err_out;
	}
	}


	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
	if (!port)
	if (!port)
		return ERR_PTR(-ENOMEM);
		goto err_out;


	rwlock_init(&port->unit_list_lock);
	rwlock_init(&port->unit_list_lock);
	INIT_LIST_HEAD(&port->unit_list);
	INIT_LIST_HEAD(&port->unit_list);


	init_waitqueue_head(&port->remove_wq);
	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
	INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
	INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
@@ -684,32 +683,28 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
	port->d_id = d_id;
	port->d_id = d_id;
	port->wwpn = wwpn;
	port->wwpn = wwpn;
	port->rport_task = RPORT_NONE;
	port->rport_task = RPORT_NONE;
	port->sysfs_device.parent = &adapter->ccw_device->dev;
	port->sysfs_device.release = zfcp_port_release;


	/* mark port unusable as long as sysfs registration is not complete */
	/* mark port unusable as long as sysfs registration is not complete */
	atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_set(&port->refcount, 0);


	if (dev_set_name(&port->sysfs_device, "0x%016llx",
	if (dev_set_name(&port->sysfs_device, "0x%016llx",
			 (unsigned long long)wwpn)) {
			 (unsigned long long)wwpn)) {
		kfree(port);
		kfree(port);
		return ERR_PTR(-ENOMEM);
		goto err_out;
	}
	}
	port->sysfs_device.parent = &adapter->ccw_device->dev;
	port->sysfs_device.release = zfcp_sysfs_port_release;
	dev_set_drvdata(&port->sysfs_device, port);
	dev_set_drvdata(&port->sysfs_device, port);
	retval = -EINVAL;


	if (device_register(&port->sysfs_device)) {
	if (device_register(&port->sysfs_device)) {
		put_device(&port->sysfs_device);
		put_device(&port->sysfs_device);
		return ERR_PTR(-EINVAL);
		goto err_out;
	}
	}


	if (sysfs_create_group(&port->sysfs_device.kobj,
	if (sysfs_create_group(&port->sysfs_device.kobj,
			       &zfcp_sysfs_port_attrs)) {
			       &zfcp_sysfs_port_attrs))
		device_unregister(&port->sysfs_device);
		goto err_out_put;
		return ERR_PTR(-EINVAL);
	}

	zfcp_port_get(port);


	write_lock_irq(&adapter->port_list_lock);
	write_lock_irq(&adapter->port_list_lock);
	list_add_tail(&port->list, &adapter->port_list);
	list_add_tail(&port->list, &adapter->port_list);
@@ -718,23 +713,13 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);


	zfcp_adapter_get(adapter);
	return port;
	return port;
}


/**
err_out_put:
 * zfcp_port_dequeue - dequeues a port from the port list of the adapter
 * @port: pointer to struct zfcp_port which should be removed
 */
void zfcp_port_dequeue(struct zfcp_port *port)
{
	struct zfcp_adapter *adapter = port->adapter;

	list_del(&port->list); /* no list locking required here */
	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
	zfcp_adapter_put(adapter);
	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
	device_unregister(&port->sysfs_device);
	device_unregister(&port->sysfs_device);
err_out:
	kref_put(&adapter->ref, zfcp_adapter_release);
	return ERR_PTR(retval);
}
}


/**
/**
+9 −7
Original line number Original line Diff line number Diff line
@@ -128,13 +128,15 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
	write_unlock_irq(&adapter->port_list_lock);
	write_unlock_irq(&adapter->port_list_lock);
	mutex_unlock(&zfcp_data.config_mutex);
	mutex_unlock(&zfcp_data.config_mutex);


	list_for_each_entry_safe(port, p, &port_remove_lh, list) {
	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
			zfcp_unit_dequeue(unit);
		zfcp_device_unregister(&unit->sysfs_device,
		zfcp_port_dequeue(port);
				       &zfcp_sysfs_unit_attrs);
	}

	wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
	list_for_each_entry_safe(port, p, &port_remove_lh, list)
	zfcp_adapter_dequeue(adapter);
		zfcp_device_unregister(&port->sysfs_device,
				       &zfcp_sysfs_port_attrs);

	kref_put(&adapter->ref, zfcp_adapter_release);
}
}


/**
/**
+2 −3
Original line number Original line Diff line number Diff line
@@ -98,7 +98,7 @@ static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
	if (!adapter)
	if (!adapter)
		goto out_put;
		goto out_put;


	zfcp_adapter_get(adapter);
	kref_get(&adapter->ref);
out_put:
out_put:
	put_device(&ccwdev->dev);
	put_device(&ccwdev->dev);
out:
out:
@@ -212,7 +212,6 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
		retval = -ENXIO;
		retval = -ENXIO;
		goto free_buffer;
		goto free_buffer;
	}
	}
	zfcp_adapter_get(adapter);


	retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
	retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
				    data_user->control_file);
				    data_user->control_file);
@@ -245,7 +244,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
 free_sg:
 free_sg:
	zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
	zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
 adapter_put:
 adapter_put:
	zfcp_adapter_put(adapter);
	kref_put(&adapter->ref, zfcp_adapter_release);
 free_buffer:
 free_buffer:
	kfree(data);
	kfree(data);
 no_mem_sense:
 no_mem_sense:
+2 −0
Original line number Original line Diff line number Diff line
@@ -1067,6 +1067,8 @@ err_out:
 */
 */
void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
{
{
	if (!dbf)
		return;
	debug_unregister(dbf->scsi);
	debug_unregister(dbf->scsi);
	debug_unregister(dbf->san);
	debug_unregister(dbf->san);
	debug_unregister(dbf->hba);
	debug_unregister(dbf->hba);
+1 −52
Original line number Original line Diff line number Diff line
@@ -446,9 +446,7 @@ struct zfcp_qdio {
};
};


struct zfcp_adapter {
struct zfcp_adapter {
	atomic_t                refcount;          /* reference count */
	struct kref		ref;
	wait_queue_head_t	remove_wq;         /* can be used to wait for
						      refcount drop to zero */
	u64			peer_wwnn;	   /* P2P peer WWNN */
	u64			peer_wwnn;	   /* P2P peer WWNN */
	u64			peer_wwpn;	   /* P2P peer WWPN */
	u64			peer_wwpn;	   /* P2P peer WWPN */
	u32			peer_d_id;	   /* P2P peer D_ID */
	u32			peer_d_id;	   /* P2P peer D_ID */
@@ -501,9 +499,6 @@ struct zfcp_port {
	struct device          sysfs_device;   /* sysfs device */
	struct device          sysfs_device;   /* sysfs device */
	struct fc_rport        *rport;         /* rport of fc transport class */
	struct fc_rport        *rport;         /* rport of fc transport class */
	struct list_head       list;	       /* list of remote ports */
	struct list_head       list;	       /* list of remote ports */
	atomic_t               refcount;       /* reference count */
	wait_queue_head_t      remove_wq;      /* can be used to wait for
						  refcount drop to zero */
	struct zfcp_adapter    *adapter;       /* adapter used to access port */
	struct zfcp_adapter    *adapter;       /* adapter used to access port */
	struct list_head	unit_list;	/* head of logical unit list */
	struct list_head	unit_list;	/* head of logical unit list */
	rwlock_t		unit_list_lock; /* unit list lock */
	rwlock_t		unit_list_lock; /* unit list lock */
@@ -525,9 +520,6 @@ struct zfcp_port {
struct zfcp_unit {
struct zfcp_unit {
	struct device          sysfs_device;   /* sysfs device */
	struct device          sysfs_device;   /* sysfs device */
	struct list_head       list;	       /* list of logical units */
	struct list_head       list;	       /* list of logical units */
	atomic_t               refcount;       /* reference count */
	wait_queue_head_t      remove_wq;      /* can be used to wait for
						  refcount drop to zero */
	struct zfcp_port       *port;	       /* remote port of unit */
	struct zfcp_port       *port;	       /* remote port of unit */
	atomic_t	       status;	       /* status of this logical unit */
	atomic_t	       status;	       /* status of this logical unit */
	u64		       fcp_lun;	       /* own FCP_LUN */
	u64		       fcp_lun;	       /* own FCP_LUN */
@@ -656,47 +648,4 @@ zfcp_reqlist_find_safe(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req)
	return NULL;
	return NULL;
}
}


/*
 *  functions needed for reference/usage counting
 */

static inline void
zfcp_unit_get(struct zfcp_unit *unit)
{
	atomic_inc(&unit->refcount);
}

static inline void
zfcp_unit_put(struct zfcp_unit *unit)
{
	if (atomic_dec_return(&unit->refcount) == 0)
		wake_up(&unit->remove_wq);
}

static inline void
zfcp_port_get(struct zfcp_port *port)
{
	atomic_inc(&port->refcount);
}

static inline void
zfcp_port_put(struct zfcp_port *port)
{
	if (atomic_dec_return(&port->refcount) == 0)
		wake_up(&port->remove_wq);
}

static inline void
zfcp_adapter_get(struct zfcp_adapter *adapter)
{
	atomic_inc(&adapter->refcount);
}

static inline void
zfcp_adapter_put(struct zfcp_adapter *adapter)
{
	if (atomic_dec_return(&adapter->refcount) == 0)
		wake_up(&adapter->remove_wq);
}

#endif /* ZFCP_DEF_H */
#endif /* ZFCP_DEF_H */
Loading