|
@@ -64,6 +64,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
64
|
64
|
*/
|
65
|
65
|
#define SAN_COMMAND_TIMEOUT ( 15 * TICKS_PER_SEC )
|
66
|
66
|
|
|
67
|
+/**
|
|
68
|
+ * Number of times to retry commands
|
|
69
|
+ *
|
|
70
|
+ * We may need to retry commands. For example, the underlying
|
|
71
|
+ * connection may be closed by the SAN target due to an inactivity
|
|
72
|
+ * timeout, or the SAN target may return pointless "error" messages
|
|
73
|
+ * such as "SCSI power-on occurred".
|
|
74
|
+ */
|
|
75
|
+#define SAN_COMMAND_MAX_RETRIES 10
|
|
76
|
+
|
67
|
77
|
/** List of SAN devices */
|
68
|
78
|
LIST_HEAD ( san_devices );
|
69
|
79
|
|
|
@@ -331,36 +341,42 @@ sandev_command ( struct san_device *sandev,
|
331
|
341
|
int ( * command ) ( struct san_device *sandev,
|
332
|
342
|
const union san_command_params *params ),
|
333
|
343
|
const union san_command_params *params ) {
|
|
344
|
+ unsigned int retries;
|
334
|
345
|
int rc;
|
335
|
346
|
|
336
|
347
|
/* Sanity check */
|
337
|
348
|
assert ( ! timer_running ( &sandev->timer ) );
|
338
|
349
|
|
339
|
|
- /* Reopen block device if applicable */
|
340
|
|
- if ( sandev_needs_reopen ( sandev ) &&
|
341
|
|
- ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) {
|
342
|
|
- goto err_reopen;
|
343
|
|
- }
|
|
350
|
+ /* (Re)try command */
|
|
351
|
+ for ( retries = 0 ; retries < SAN_COMMAND_MAX_RETRIES ; retries++ ) {
|
344
|
352
|
|
345
|
|
- /* Start expiry timer */
|
346
|
|
- start_timer_fixed ( &sandev->timer, SAN_COMMAND_TIMEOUT );
|
|
353
|
+ /* Reopen block device if applicable */
|
|
354
|
+ if ( sandev_needs_reopen ( sandev ) &&
|
|
355
|
+ ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) {
|
|
356
|
+ continue;
|
|
357
|
+ }
|
347
|
358
|
|
348
|
|
- /* Initiate command */
|
349
|
|
- if ( ( rc = command ( sandev, params ) ) != 0 )
|
350
|
|
- goto err_op;
|
|
359
|
+ /* Start expiry timer */
|
|
360
|
+ start_timer_fixed ( &sandev->timer, SAN_COMMAND_TIMEOUT );
|
351
|
361
|
|
352
|
|
- /* Wait for command to complete */
|
353
|
|
- while ( timer_running ( &sandev->timer ) )
|
354
|
|
- step();
|
|
362
|
+ /* Initiate command */
|
|
363
|
+ if ( ( rc = command ( sandev, params ) ) != 0 ) {
|
|
364
|
+ stop_timer ( &sandev->timer );
|
|
365
|
+ continue;
|
|
366
|
+ }
|
355
|
367
|
|
356
|
|
- /* Collect return status */
|
357
|
|
- rc = sandev->command_rc;
|
|
368
|
+ /* Wait for command to complete */
|
|
369
|
+ while ( timer_running ( &sandev->timer ) )
|
|
370
|
+ step();
|
358
|
371
|
|
359
|
|
- return rc;
|
|
372
|
+ /* Exit on success */
|
|
373
|
+ if ( ( rc = sandev->command_rc ) == 0 )
|
|
374
|
+ return 0;
|
|
375
|
+ }
|
|
376
|
+
|
|
377
|
+ /* Sanity check */
|
|
378
|
+ assert ( ! timer_running ( &sandev->timer ) );
|
360
|
379
|
|
361
|
|
- err_op:
|
362
|
|
- stop_timer ( &sandev->timer );
|
363
|
|
- err_reopen:
|
364
|
380
|
return rc;
|
365
|
381
|
}
|
366
|
382
|
|