diff options
author | Horst Hummel <horst.hummel@de.ibm.com> | 2006-01-06 03:19:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:50 -0500 |
commit | 1c01b8a5963aec60488c1c97d67cffd8b5275e3f (patch) | |
tree | 48eb6c300541d77ff2cc5d8949ce5788fab1d82f /drivers/s390 | |
parent | 9a7af289660dc749d7c58234191601046a9bf488 (diff) |
[PATCH] s390: dasd failfast support
To properly support multipath-failover handling, the linux block layer has
introduced a special request flag, 'REQ_FAILFAST'. This flag is now used to
return requests immediately in case the device is not operational.
Signed-off-by: Horst Hummel <horst.hummel@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 28 | ||||
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 4 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 7 | ||||
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 4 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 3 |
5 files changed, 34 insertions, 12 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 62787393a209..1141a5963b67 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 |
9 | * | 9 | * |
10 | * $Revision: 1.169 $ | 10 | * $Revision: 1.172 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -1224,6 +1224,12 @@ __dasd_start_head(struct dasd_device * device) | |||
1224 | if (list_empty(&device->ccw_queue)) | 1224 | if (list_empty(&device->ccw_queue)) |
1225 | return; | 1225 | return; |
1226 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1226 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); |
1227 | /* check FAILFAST */ | ||
1228 | if (device->stopped & ~DASD_STOPPED_PENDING && | ||
1229 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) { | ||
1230 | cqr->status = DASD_CQR_FAILED; | ||
1231 | dasd_schedule_bh(device); | ||
1232 | } | ||
1227 | if ((cqr->status == DASD_CQR_QUEUED) && | 1233 | if ((cqr->status == DASD_CQR_QUEUED) && |
1228 | (!device->stopped)) { | 1234 | (!device->stopped)) { |
1229 | /* try to start the first I/O that can be started */ | 1235 | /* try to start the first I/O that can be started */ |
@@ -1750,8 +1756,10 @@ dasd_exit(void) | |||
1750 | * SECTION: common functions for ccw_driver use | 1756 | * SECTION: common functions for ccw_driver use |
1751 | */ | 1757 | */ |
1752 | 1758 | ||
1753 | /* initial attempt at a probe function. this can be simplified once | 1759 | /* |
1754 | * the other detection code is gone */ | 1760 | * Initial attempt at a probe function. this can be simplified once |
1761 | * the other detection code is gone. | ||
1762 | */ | ||
1755 | int | 1763 | int |
1756 | dasd_generic_probe (struct ccw_device *cdev, | 1764 | dasd_generic_probe (struct ccw_device *cdev, |
1757 | struct dasd_discipline *discipline) | 1765 | struct dasd_discipline *discipline) |
@@ -1770,8 +1778,10 @@ dasd_generic_probe (struct ccw_device *cdev, | |||
1770 | return ret; | 1778 | return ret; |
1771 | } | 1779 | } |
1772 | 1780 | ||
1773 | /* this will one day be called from a global not_oper handler. | 1781 | /* |
1774 | * It is also used by driver_unregister during module unload */ | 1782 | * This will one day be called from a global not_oper handler. |
1783 | * It is also used by driver_unregister during module unload. | ||
1784 | */ | ||
1775 | void | 1785 | void |
1776 | dasd_generic_remove (struct ccw_device *cdev) | 1786 | dasd_generic_remove (struct ccw_device *cdev) |
1777 | { | 1787 | { |
@@ -1798,9 +1808,11 @@ dasd_generic_remove (struct ccw_device *cdev) | |||
1798 | dasd_delete_device(device); | 1808 | dasd_delete_device(device); |
1799 | } | 1809 | } |
1800 | 1810 | ||
1801 | /* activate a device. This is called from dasd_{eckd,fba}_probe() when either | 1811 | /* |
1812 | * Activate a device. This is called from dasd_{eckd,fba}_probe() when either | ||
1802 | * the device is detected for the first time and is supposed to be used | 1813 | * the device is detected for the first time and is supposed to be used |
1803 | * or the user has started activation through sysfs */ | 1814 | * or the user has started activation through sysfs. |
1815 | */ | ||
1804 | int | 1816 | int |
1805 | dasd_generic_set_online (struct ccw_device *cdev, | 1817 | dasd_generic_set_online (struct ccw_device *cdev, |
1806 | struct dasd_discipline *discipline) | 1818 | struct dasd_discipline *discipline) |
@@ -1917,7 +1929,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
1917 | if (cqr->status == DASD_CQR_IN_IO) | 1929 | if (cqr->status == DASD_CQR_IN_IO) |
1918 | cqr->status = DASD_CQR_FAILED; | 1930 | cqr->status = DASD_CQR_FAILED; |
1919 | device->stopped |= DASD_STOPPED_DC_EIO; | 1931 | device->stopped |= DASD_STOPPED_DC_EIO; |
1920 | dasd_schedule_bh(device); | ||
1921 | } else { | 1932 | } else { |
1922 | list_for_each_entry(cqr, &device->ccw_queue, list) | 1933 | list_for_each_entry(cqr, &device->ccw_queue, list) |
1923 | if (cqr->status == DASD_CQR_IN_IO) { | 1934 | if (cqr->status == DASD_CQR_IN_IO) { |
@@ -1927,6 +1938,7 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
1927 | device->stopped |= DASD_STOPPED_DC_WAIT; | 1938 | device->stopped |= DASD_STOPPED_DC_WAIT; |
1928 | dasd_set_timer(device, 0); | 1939 | dasd_set_timer(device, 0); |
1929 | } | 1940 | } |
1941 | dasd_schedule_bh(device); | ||
1930 | ret = 1; | 1942 | ret = 1; |
1931 | break; | 1943 | break; |
1932 | case CIO_OPER: | 1944 | case CIO_OPER: |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 16c4b7d94bd7..a33d4064b537 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Bugreports.to..: <Linux390@de.ibm.com> | 6 | * Bugreports.to..: <Linux390@de.ibm.com> |
7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
8 | * | 8 | * |
9 | * $Revision: 1.52 $ | 9 | * $Revision: 1.53 $ |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
@@ -549,6 +549,8 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) | |||
549 | } | 549 | } |
550 | cqr->retries = DIAG_MAX_RETRIES; | 550 | cqr->retries = DIAG_MAX_RETRIES; |
551 | cqr->buildclk = get_clock(); | 551 | cqr->buildclk = get_clock(); |
552 | if (req->flags & REQ_FAILFAST) | ||
553 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | ||
552 | cqr->device = device; | 554 | cqr->device = device; |
553 | cqr->expires = DIAG_TIMEOUT; | 555 | cqr->expires = DIAG_TIMEOUT; |
554 | cqr->status = DASD_CQR_FILLED; | 556 | cqr->status = DASD_CQR_FILLED; |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 811060e10c00..efc4cf62496e 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
9 | * | 9 | * |
10 | * $Revision: 1.71 $ | 10 | * $Revision: 1.74 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -1136,6 +1136,8 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req) | |||
1136 | recid++; | 1136 | recid++; |
1137 | } | 1137 | } |
1138 | } | 1138 | } |
1139 | if (req->flags & REQ_FAILFAST) | ||
1140 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | ||
1139 | cqr->device = device; | 1141 | cqr->device = device; |
1140 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 1142 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ |
1141 | cqr->lpm = private->path_data.ppm; | 1143 | cqr->lpm = private->path_data.ppm; |
@@ -1252,6 +1254,7 @@ dasd_eckd_release(struct block_device *bdev, int no, long args) | |||
1252 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; | 1254 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; |
1253 | cqr->device = device; | 1255 | cqr->device = device; |
1254 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 1256 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
1257 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | ||
1255 | cqr->retries = 0; | 1258 | cqr->retries = 0; |
1256 | cqr->expires = 2 * HZ; | 1259 | cqr->expires = 2 * HZ; |
1257 | cqr->buildclk = get_clock(); | 1260 | cqr->buildclk = get_clock(); |
@@ -1296,6 +1299,7 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args) | |||
1296 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; | 1299 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; |
1297 | cqr->device = device; | 1300 | cqr->device = device; |
1298 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 1301 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
1302 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | ||
1299 | cqr->retries = 0; | 1303 | cqr->retries = 0; |
1300 | cqr->expires = 2 * HZ; | 1304 | cqr->expires = 2 * HZ; |
1301 | cqr->buildclk = get_clock(); | 1305 | cqr->buildclk = get_clock(); |
@@ -1339,6 +1343,7 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args) | |||
1339 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; | 1343 | cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; |
1340 | cqr->device = device; | 1344 | cqr->device = device; |
1341 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | 1345 | clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); |
1346 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | ||
1342 | cqr->retries = 0; | 1347 | cqr->retries = 0; |
1343 | cqr->expires = 2 * HZ; | 1348 | cqr->expires = 2 * HZ; |
1344 | cqr->buildclk = get_clock(); | 1349 | cqr->buildclk = get_clock(); |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 28cb4613b7f5..9bac8d87a9cc 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Bugreports.to..: <Linux390@de.ibm.com> | 4 | * Bugreports.to..: <Linux390@de.ibm.com> |
5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
6 | * | 6 | * |
7 | * $Revision: 1.40 $ | 7 | * $Revision: 1.41 $ |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
@@ -352,6 +352,8 @@ dasd_fba_build_cp(struct dasd_device * device, struct request *req) | |||
352 | recid++; | 352 | recid++; |
353 | } | 353 | } |
354 | } | 354 | } |
355 | if (req->flags & REQ_FAILFAST) | ||
356 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | ||
355 | cqr->device = device; | 357 | cqr->device = device; |
356 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 358 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ |
357 | cqr->retries = 32; | 359 | cqr->retries = 32; |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 9fab04f3056d..2fb05c4a528c 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Bugreports.to..: <Linux390@de.ibm.com> | 6 | * Bugreports.to..: <Linux390@de.ibm.com> |
7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | 7 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 |
8 | * | 8 | * |
9 | * $Revision: 1.65 $ | 9 | * $Revision: 1.68 $ |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef DASD_INT_H | 12 | #ifndef DASD_INT_H |
@@ -208,6 +208,7 @@ struct dasd_ccw_req { | |||
208 | 208 | ||
209 | /* per dasd_ccw_req flags */ | 209 | /* per dasd_ccw_req flags */ |
210 | #define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ | 210 | #define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ |
211 | #define DASD_CQR_FLAGS_FAILFAST 1 /* FAILFAST */ | ||
211 | 212 | ||
212 | /* Signature for error recovery functions. */ | 213 | /* Signature for error recovery functions. */ |
213 | typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); | 214 | typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); |