Explorar el Código

[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>
tags/v1.20.1
Michael Brown hace 7 años
padre
commit
f450c75dad
Se han modificado 1 ficheros con 9 adiciones y 4 borrados
  1. 9
    4
      src/core/interface.c

+ 9
- 4
src/core/interface.c Ver fichero

271
  * unplugs the interface.
271
  * unplugs the interface.
272
  */
272
  */
273
 void intf_shutdown ( struct interface *intf, int rc ) {
273
 void intf_shutdown ( struct interface *intf, int rc ) {
274
+	struct interface tmp;
274
 
275
 
275
 	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
276
 	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " shutting down (%s)\n",
276
 	       INTF_DBG ( intf ), strerror ( rc ) );
277
 	       INTF_DBG ( intf ), strerror ( rc ) );
278
 	/* Block further operations */
279
 	/* Block further operations */
279
 	intf_nullify ( intf );
280
 	intf_nullify ( intf );
280
 
281
 
281
-	/* Notify destination of close */
282
-	intf_close ( intf, rc );
282
+	/* Transfer destination to temporary interface */
283
+	tmp.dest = intf->dest;
284
+	intf->dest = &null_intf;
285
+
286
+	/* Notify destination of close via temporary interface */
287
+	intf_close ( &tmp, rc );
283
 
288
 
284
-	/* Unplug interface */
285
-	intf_unplug ( intf );
289
+	/* Unplug temporary interface */
290
+	intf_unplug ( &tmp );
286
 }
291
 }
287
 
292
 
288
 /**
293
 /**

Loading…
Cancelar
Guardar