diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2008-10-01 06:42:17 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-03 13:11:53 -0400 |
commit | 5ab944f97e09a3d52951fe903eed9a7b88d810b2 (patch) | |
tree | 266171323bd7c5dfc433efd70ca19aafc891598c /drivers/s390/scsi/zfcp_aux.c | |
parent | 44cc76f2d154aa24340354b4711a0fe7f8f08adc (diff) |
[SCSI] zfcp: attach and release SAN nameserver port on demand
Changing the zfcp behaviour from always having the nameserver port
open to an on-demand strategy. This strategy reduces the use of
limited resources like port connections. The patch provides a common
infrastructure which could be used for all WKA ports in future.
Also reduce the number of nameserver lookups by changing the zfcp
behaviour of always querying the nameserver for the corresponding
destination ID of the remote port. If the destination ID has changed
during the reopen process we will be informed and then trigger a
nameserver query on demand.
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 65 |
1 files changed, 7 insertions, 58 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index ee13a455c823..181f88bb53b3 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -450,19 +450,6 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) | |||
450 | stat_work)); | 450 | stat_work)); |
451 | } | 451 | } |
452 | 452 | ||
453 | static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) | ||
454 | { | ||
455 | struct zfcp_port *port; | ||
456 | |||
457 | port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, | ||
458 | ZFCP_DID_DIRECTORY_SERVICE); | ||
459 | if (IS_ERR(port)) | ||
460 | return PTR_ERR(port); | ||
461 | zfcp_port_put(port); | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | /** | 453 | /** |
467 | * zfcp_adapter_enqueue - enqueue a new adapter to the list | 454 | * zfcp_adapter_enqueue - enqueue a new adapter to the list |
468 | * @ccw_device: pointer to the struct cc_device | 455 | * @ccw_device: pointer to the struct cc_device |
@@ -552,7 +539,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
552 | 539 | ||
553 | zfcp_data.adapters++; | 540 | zfcp_data.adapters++; |
554 | 541 | ||
555 | zfcp_nameserver_enqueue(adapter); | 542 | zfcp_fc_nameserver_init(adapter); |
556 | 543 | ||
557 | return 0; | 544 | return 0; |
558 | 545 | ||
@@ -638,7 +625,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
638 | { | 625 | { |
639 | struct zfcp_port *port; | 626 | struct zfcp_port *port; |
640 | int retval; | 627 | int retval; |
641 | char *bus_id; | ||
642 | 628 | ||
643 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); | 629 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); |
644 | if (!port) | 630 | if (!port) |
@@ -648,6 +634,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
648 | 634 | ||
649 | INIT_LIST_HEAD(&port->unit_list_head); | 635 | INIT_LIST_HEAD(&port->unit_list_head); |
650 | INIT_LIST_HEAD(&port->unit_remove_lh); | 636 | INIT_LIST_HEAD(&port->unit_remove_lh); |
637 | INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup); | ||
651 | 638 | ||
652 | port->adapter = adapter; | 639 | port->adapter = adapter; |
653 | port->d_id = d_id; | 640 | port->d_id = d_id; |
@@ -657,34 +644,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
657 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); | 644 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); |
658 | atomic_set(&port->refcount, 0); | 645 | atomic_set(&port->refcount, 0); |
659 | 646 | ||
660 | if (status & ZFCP_STATUS_PORT_WKA) { | 647 | snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", wwpn); |
661 | switch (d_id) { | 648 | port->sysfs_device.parent = &adapter->ccw_device->dev; |
662 | case ZFCP_DID_DIRECTORY_SERVICE: | ||
663 | bus_id = "directory"; | ||
664 | break; | ||
665 | case ZFCP_DID_MANAGEMENT_SERVICE: | ||
666 | bus_id = "management"; | ||
667 | break; | ||
668 | case ZFCP_DID_KEY_DISTRIBUTION_SERVICE: | ||
669 | bus_id = "key_distribution"; | ||
670 | break; | ||
671 | case ZFCP_DID_ALIAS_SERVICE: | ||
672 | bus_id = "alias"; | ||
673 | break; | ||
674 | case ZFCP_DID_TIME_SERVICE: | ||
675 | bus_id = "time"; | ||
676 | break; | ||
677 | default: | ||
678 | kfree(port); | ||
679 | return ERR_PTR(-EINVAL); | ||
680 | } | ||
681 | snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "%s", bus_id); | ||
682 | port->sysfs_device.parent = &adapter->generic_services; | ||
683 | } else { | ||
684 | snprintf(port->sysfs_device.bus_id, | ||
685 | BUS_ID_SIZE, "0x%016llx", wwpn); | ||
686 | port->sysfs_device.parent = &adapter->ccw_device->dev; | ||
687 | } | ||
688 | 649 | ||
689 | port->sysfs_device.release = zfcp_sysfs_port_release; | 650 | port->sysfs_device.release = zfcp_sysfs_port_release; |
690 | dev_set_drvdata(&port->sysfs_device, port); | 651 | dev_set_drvdata(&port->sysfs_device, port); |
@@ -700,12 +661,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
700 | if (device_register(&port->sysfs_device)) | 661 | if (device_register(&port->sysfs_device)) |
701 | goto err_out_free; | 662 | goto err_out_free; |
702 | 663 | ||
703 | if (status & ZFCP_STATUS_PORT_WKA) | 664 | retval = sysfs_create_group(&port->sysfs_device.kobj, |
704 | retval = sysfs_create_group(&port->sysfs_device.kobj, | 665 | &zfcp_sysfs_port_attrs); |
705 | &zfcp_sysfs_ns_port_attrs); | ||
706 | else | ||
707 | retval = sysfs_create_group(&port->sysfs_device.kobj, | ||
708 | &zfcp_sysfs_port_attrs); | ||
709 | 666 | ||
710 | if (retval) { | 667 | if (retval) { |
711 | device_unregister(&port->sysfs_device); | 668 | device_unregister(&port->sysfs_device); |
@@ -718,9 +675,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
718 | list_add_tail(&port->list, &adapter->port_list_head); | 675 | list_add_tail(&port->list, &adapter->port_list_head); |
719 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | 676 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); |
720 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); | 677 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); |
721 | if (d_id == ZFCP_DID_DIRECTORY_SERVICE) | ||
722 | if (!adapter->nameserver_port) | ||
723 | adapter->nameserver_port = port; | ||
724 | adapter->ports++; | 678 | adapter->ports++; |
725 | 679 | ||
726 | write_unlock_irq(&zfcp_data.config_lock); | 680 | write_unlock_irq(&zfcp_data.config_lock); |
@@ -749,12 +703,7 @@ void zfcp_port_dequeue(struct zfcp_port *port) | |||
749 | fc_remote_port_delete(port->rport); | 703 | fc_remote_port_delete(port->rport); |
750 | port->rport = NULL; | 704 | port->rport = NULL; |
751 | zfcp_adapter_put(port->adapter); | 705 | zfcp_adapter_put(port->adapter); |
752 | if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA) | 706 | sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs); |
753 | sysfs_remove_group(&port->sysfs_device.kobj, | ||
754 | &zfcp_sysfs_ns_port_attrs); | ||
755 | else | ||
756 | sysfs_remove_group(&port->sysfs_device.kobj, | ||
757 | &zfcp_sysfs_port_attrs); | ||
758 | device_unregister(&port->sysfs_device); | 707 | device_unregister(&port->sysfs_device); |
759 | } | 708 | } |
760 | 709 | ||