diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2008-08-19 19:45:30 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-13 09:28:52 -0400 |
commit | 6000a368cd8e6da1caf101411bdb494cd6fb8b09 (patch) | |
tree | 4cd3333af00182e915aa96ffa49069f5f76976dc /drivers | |
parent | 056a44834950ffa51fafa6c76a720fa32e86851a (diff) |
[SCSI] block: separate failfast into multiple bits.
Multipath is best at handling transport errors. If it gets a device
error then there is not much the multipath layer can do. It will just
access the same device but from a different path.
This patch breaks up failfast into device, transport and driver errors.
The multipath layers (md and dm mutlipath) only ask the lower levels to
fast fail transport errors. The user of failfast, read ahead, will ask
to fast fail on all errors.
Note that blk_noretry_request will return true if any failfast bit
is set. This allows drivers that do not support the multipath failfast
bits to continue to fail on any failfast error like before. Drivers
like scsi that are able to fail fast specific errors can check
for the specific fail fast type. In the next patch I will convert
scsi.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm-mpath.c | 2 | ||||
-rw-r--r-- | drivers/md/multipath.c | 4 | ||||
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 2 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_alua.c | 3 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_emc.c | 3 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_hp_sw.c | 6 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_rdac.c | 3 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_spi.c | 4 |
10 files changed, 19 insertions, 12 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 103304c1e3b0..9bf3460c5540 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -849,7 +849,7 @@ static int multipath_map(struct dm_target *ti, struct bio *bio, | |||
849 | dm_bio_record(&mpio->details, bio); | 849 | dm_bio_record(&mpio->details, bio); |
850 | 850 | ||
851 | map_context->ptr = mpio; | 851 | map_context->ptr = mpio; |
852 | bio->bi_rw |= (1 << BIO_RW_FAILFAST); | 852 | bio->bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); |
853 | r = map_io(m, bio, mpio, 0); | 853 | r = map_io(m, bio, mpio, 0); |
854 | if (r < 0 || r == DM_MAPIO_REQUEUE) | 854 | if (r < 0 || r == DM_MAPIO_REQUEUE) |
855 | mempool_free(mpio, m->mpio_pool); | 855 | mempool_free(mpio, m->mpio_pool); |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 8bb8794129b3..7ae33ebaf7ec 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -176,7 +176,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio) | |||
176 | mp_bh->bio = *bio; | 176 | mp_bh->bio = *bio; |
177 | mp_bh->bio.bi_sector += multipath->rdev->data_offset; | 177 | mp_bh->bio.bi_sector += multipath->rdev->data_offset; |
178 | mp_bh->bio.bi_bdev = multipath->rdev->bdev; | 178 | mp_bh->bio.bi_bdev = multipath->rdev->bdev; |
179 | mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST); | 179 | mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); |
180 | mp_bh->bio.bi_end_io = multipath_end_request; | 180 | mp_bh->bio.bi_end_io = multipath_end_request; |
181 | mp_bh->bio.bi_private = mp_bh; | 181 | mp_bh->bio.bi_private = mp_bh; |
182 | generic_make_request(&mp_bh->bio); | 182 | generic_make_request(&mp_bh->bio); |
@@ -402,7 +402,7 @@ static void multipathd (mddev_t *mddev) | |||
402 | *bio = *(mp_bh->master_bio); | 402 | *bio = *(mp_bh->master_bio); |
403 | bio->bi_sector += conf->multipaths[mp_bh->path].rdev->data_offset; | 403 | bio->bi_sector += conf->multipaths[mp_bh->path].rdev->data_offset; |
404 | bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev; | 404 | bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev; |
405 | bio->bi_rw |= (1 << BIO_RW_FAILFAST); | 405 | bio->bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); |
406 | bio->bi_end_io = multipath_end_request; | 406 | bio->bi_end_io = multipath_end_request; |
407 | bio->bi_private = mp_bh; | 407 | bio->bi_private = mp_bh; |
408 | generic_make_request(bio); | 408 | generic_make_request(bio); |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 85fcb4371054..7844461a995b 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -544,7 +544,7 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev, | |||
544 | } | 544 | } |
545 | cqr->retries = DIAG_MAX_RETRIES; | 545 | cqr->retries = DIAG_MAX_RETRIES; |
546 | cqr->buildclk = get_clock(); | 546 | cqr->buildclk = get_clock(); |
547 | if (req->cmd_flags & REQ_FAILFAST) | 547 | if (blk_noretry_request(req)) |
548 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 548 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
549 | cqr->startdev = memdev; | 549 | cqr->startdev = memdev; |
550 | cqr->memdev = memdev; | 550 | cqr->memdev = memdev; |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 49f9d221e23d..2e60d5f968c8 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1700,7 +1700,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, | |||
1700 | recid++; | 1700 | recid++; |
1701 | } | 1701 | } |
1702 | } | 1702 | } |
1703 | if (req->cmd_flags & REQ_FAILFAST) | 1703 | if (blk_noretry_request(req)) |
1704 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 1704 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
1705 | cqr->startdev = startdev; | 1705 | cqr->startdev = startdev; |
1706 | cqr->memdev = startdev; | 1706 | cqr->memdev = startdev; |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 93d9b6452a94..7d442aeff3d1 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -355,7 +355,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, | |||
355 | recid++; | 355 | recid++; |
356 | } | 356 | } |
357 | } | 357 | } |
358 | if (req->cmd_flags & REQ_FAILFAST) | 358 | if (blk_noretry_request(req)) |
359 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 359 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
360 | cqr->startdev = memdev; | 360 | cqr->startdev = memdev; |
361 | cqr->memdev = memdev; | 361 | cqr->memdev = memdev; |
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 708e475896b9..cb8aa3b58c22 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -109,7 +109,8 @@ static struct request *get_alua_req(struct scsi_device *sdev, | |||
109 | } | 109 | } |
110 | 110 | ||
111 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 111 | rq->cmd_type = REQ_TYPE_BLOCK_PC; |
112 | rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; | 112 | rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
113 | REQ_FAILFAST_DRIVER | REQ_NOMERGE; | ||
113 | rq->retries = ALUA_FAILOVER_RETRIES; | 114 | rq->retries = ALUA_FAILOVER_RETRIES; |
114 | rq->timeout = ALUA_FAILOVER_TIMEOUT; | 115 | rq->timeout = ALUA_FAILOVER_TIMEOUT; |
115 | 116 | ||
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 8f45570a8a01..0e572d2c5b0a 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -303,7 +303,8 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, | |||
303 | 303 | ||
304 | rq->cmd[4] = len; | 304 | rq->cmd[4] = len; |
305 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 305 | rq->cmd_type = REQ_TYPE_BLOCK_PC; |
306 | rq->cmd_flags |= REQ_FAILFAST; | 306 | rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
307 | REQ_FAILFAST_DRIVER; | ||
307 | rq->timeout = CLARIION_TIMEOUT; | 308 | rq->timeout = CLARIION_TIMEOUT; |
308 | rq->retries = CLARIION_RETRIES; | 309 | rq->retries = CLARIION_RETRIES; |
309 | 310 | ||
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 5e93c88ad66b..9aec4ca64e56 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c | |||
@@ -112,7 +112,8 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) | |||
112 | return SCSI_DH_RES_TEMP_UNAVAIL; | 112 | return SCSI_DH_RES_TEMP_UNAVAIL; |
113 | 113 | ||
114 | req->cmd_type = REQ_TYPE_BLOCK_PC; | 114 | req->cmd_type = REQ_TYPE_BLOCK_PC; |
115 | req->cmd_flags |= REQ_FAILFAST; | 115 | req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
116 | REQ_FAILFAST_DRIVER; | ||
116 | req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY); | 117 | req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY); |
117 | req->cmd[0] = TEST_UNIT_READY; | 118 | req->cmd[0] = TEST_UNIT_READY; |
118 | req->timeout = HP_SW_TIMEOUT; | 119 | req->timeout = HP_SW_TIMEOUT; |
@@ -204,7 +205,8 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) | |||
204 | return SCSI_DH_RES_TEMP_UNAVAIL; | 205 | return SCSI_DH_RES_TEMP_UNAVAIL; |
205 | 206 | ||
206 | req->cmd_type = REQ_TYPE_BLOCK_PC; | 207 | req->cmd_type = REQ_TYPE_BLOCK_PC; |
207 | req->cmd_flags |= REQ_FAILFAST; | 208 | req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
209 | REQ_FAILFAST_DRIVER; | ||
208 | req->cmd_len = COMMAND_SIZE(START_STOP); | 210 | req->cmd_len = COMMAND_SIZE(START_STOP); |
209 | req->cmd[0] = START_STOP; | 211 | req->cmd[0] = START_STOP; |
210 | req->cmd[4] = 1; /* Start spin cycle */ | 212 | req->cmd[4] = 1; /* Start spin cycle */ |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 50bf95f3b5c4..a43c3ed4df28 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
@@ -226,7 +226,8 @@ static struct request *get_rdac_req(struct scsi_device *sdev, | |||
226 | } | 226 | } |
227 | 227 | ||
228 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 228 | rq->cmd_type = REQ_TYPE_BLOCK_PC; |
229 | rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; | 229 | rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
230 | REQ_FAILFAST_DRIVER; | ||
230 | rq->retries = RDAC_RETRIES; | 231 | rq->retries = RDAC_RETRIES; |
231 | rq->timeout = RDAC_TIMEOUT; | 232 | rq->timeout = RDAC_TIMEOUT; |
232 | 233 | ||
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index b29360ed0bdc..7c2d28924d2a 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
@@ -109,7 +109,9 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, | |||
109 | for(i = 0; i < DV_RETRIES; i++) { | 109 | for(i = 0; i < DV_RETRIES; i++) { |
110 | result = scsi_execute(sdev, cmd, dir, buffer, bufflen, | 110 | result = scsi_execute(sdev, cmd, dir, buffer, bufflen, |
111 | sense, DV_TIMEOUT, /* retries */ 1, | 111 | sense, DV_TIMEOUT, /* retries */ 1, |
112 | REQ_FAILFAST); | 112 | REQ_FAILFAST_DEV | |
113 | REQ_FAILFAST_TRANSPORT | | ||
114 | REQ_FAILFAST_DRIVER); | ||
113 | if (result & DRIVER_SENSE) { | 115 | if (result & DRIVER_SENSE) { |
114 | struct scsi_sense_hdr sshdr_tmp; | 116 | struct scsi_sense_hdr sshdr_tmp; |
115 | if (!sshdr) | 117 | if (!sshdr) |