mirror of https://github.com/ipxe/ipxe.git
[interface] Unplug interface before calling intf_close() in intf_shutdown()
The call to intf_close() may result in the original interface being reopened. For example: when reading the capacity of a 2TB+ disk via iSCSI, the SCSI layer will respond to the intf_close() from the READ CAPACITY (10) command by immediately issuing a READ CAPACITY (16) command. The iSCSI layer happens to reuse the same interface for the new command (since it allows only a single concurrent command). Currently, intf_shutdown() unplugs the interface after the call to intf_close() returns. In the above scenario, this results in unplugging the just-reopened interface. Fix by transferring the interface destination (and its reference) to a temporary interface, and so effectively performing the unplug before making the call to intf_close(). Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/58/merge
parent
5ff13830ec
commit
f450c75dad
|
@ -271,6 +271,7 @@ void intf_close ( struct interface *intf, int rc ) {
|
||||||
* unplugs the interface.
|
* unplugs the interface.
|
||||||
*/
|
*/
|
||||||
void intf_shutdown ( struct interface *intf, int rc ) {
|
void intf_shutdown ( struct interface *intf, int rc ) {
|
||||||
|
struct interface tmp;
|
||||||
|
|
||||||
DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
|
DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
|
||||||
INTF_DBG ( intf ), strerror ( rc ) );
|
INTF_DBG ( intf ), strerror ( rc ) );
|
||||||
|
@ -278,11 +279,15 @@ void intf_shutdown ( struct interface *intf, int rc ) {
|
||||||
/* Block further operations */
|
/* Block further operations */
|
||||||
intf_nullify ( intf );
|
intf_nullify ( intf );
|
||||||
|
|
||||||
/* Notify destination of close */
|
/* Transfer destination to temporary interface */
|
||||||
intf_close ( intf, rc );
|
tmp.dest = intf->dest;
|
||||||
|
intf->dest = &null_intf;
|
||||||
|
|
||||||
/* Unplug interface */
|
/* Notify destination of close via temporary interface */
|
||||||
intf_unplug ( intf );
|
intf_close ( &tmp, rc );
|
||||||
|
|
||||||
|
/* Unplug temporary interface */
|
||||||
|
intf_unplug ( &tmp );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue