diff options
| author | Holger Smolinski <Holger.Smolinski@de.ibm.com> | 2009-01-09 06:14:51 -0500 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-01-09 06:15:05 -0500 |
| commit | 13de227bcd80fbdaeebe1f31154487dddb7d5b1e (patch) | |
| tree | 3f37f92d9fd5dd3c155544afb06cfe8117ec708c | |
| parent | 1301809bcee33c2153605b4387c57fab75f9800a (diff) | |
[S390] dasd: add device attribute to disable blocking on lost paths
When the connection between host and storage server is lost, the
dasd device driver usually blocks all I/O on affected devices and
waits for them to reappear. In some setups however it would be
better if the I/O is returned as error so that device can be
recovered by some other means, eg. in a raid or multipath setup.
Signed-off-by: Holger Smolinski <Holger.Smolinski@de.ibm.com>
Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
| -rw-r--r-- | arch/s390/include/asm/dasd.h | 1 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_devmap.c | 48 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_diag.c | 3 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_eckd.c | 3 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_fba.c | 3 |
5 files changed, 55 insertions, 3 deletions
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/asm/dasd.h index 55b2b80cdf6e..fb50a7864dd5 100644 --- a/arch/s390/include/asm/dasd.h +++ b/arch/s390/include/asm/dasd.h | |||
| @@ -78,6 +78,7 @@ typedef struct dasd_information2_t { | |||
| 78 | #define DASD_FEATURE_USEDIAG 0x02 | 78 | #define DASD_FEATURE_USEDIAG 0x02 |
| 79 | #define DASD_FEATURE_INITIAL_ONLINE 0x04 | 79 | #define DASD_FEATURE_INITIAL_ONLINE 0x04 |
| 80 | #define DASD_FEATURE_ERPLOG 0x08 | 80 | #define DASD_FEATURE_ERPLOG 0x08 |
| 81 | #define DASD_FEATURE_FAILFAST 0x10 | ||
| 81 | 82 | ||
| 82 | #define DASD_PARTN_BITS 2 | 83 | #define DASD_PARTN_BITS 2 |
| 83 | 84 | ||
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 2ef25731d197..300e28a531f8 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
| @@ -206,6 +206,8 @@ dasd_feature_list(char *str, char **endp) | |||
| 206 | features |= DASD_FEATURE_USEDIAG; | 206 | features |= DASD_FEATURE_USEDIAG; |
| 207 | else if (len == 6 && !strncmp(str, "erplog", 6)) | 207 | else if (len == 6 && !strncmp(str, "erplog", 6)) |
| 208 | features |= DASD_FEATURE_ERPLOG; | 208 | features |= DASD_FEATURE_ERPLOG; |
| 209 | else if (len == 8 && !strncmp(str, "failfast", 8)) | ||
| 210 | features |= DASD_FEATURE_FAILFAST; | ||
| 209 | else { | 211 | else { |
| 210 | MESSAGE(KERN_WARNING, | 212 | MESSAGE(KERN_WARNING, |
| 211 | "unsupported feature: %*s, " | 213 | "unsupported feature: %*s, " |
| @@ -667,6 +669,51 @@ dasd_device_from_cdev(struct ccw_device *cdev) | |||
| 667 | */ | 669 | */ |
| 668 | 670 | ||
| 669 | /* | 671 | /* |
| 672 | * failfast controls the behaviour, if no path is available | ||
| 673 | */ | ||
| 674 | static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr, | ||
| 675 | char *buf) | ||
| 676 | { | ||
| 677 | struct dasd_devmap *devmap; | ||
| 678 | int ff_flag; | ||
| 679 | |||
| 680 | devmap = dasd_find_busid(dev->bus_id); | ||
| 681 | if (!IS_ERR(devmap)) | ||
| 682 | ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0; | ||
| 683 | else | ||
| 684 | ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0; | ||
| 685 | return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n"); | ||
| 686 | } | ||
| 687 | |||
| 688 | static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr, | ||
| 689 | const char *buf, size_t count) | ||
| 690 | { | ||
| 691 | struct dasd_devmap *devmap; | ||
| 692 | int val; | ||
| 693 | char *endp; | ||
| 694 | |||
| 695 | devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); | ||
| 696 | if (IS_ERR(devmap)) | ||
| 697 | return PTR_ERR(devmap); | ||
| 698 | |||
| 699 | val = simple_strtoul(buf, &endp, 0); | ||
| 700 | if (((endp + 1) < (buf + count)) || (val > 1)) | ||
| 701 | return -EINVAL; | ||
| 702 | |||
| 703 | spin_lock(&dasd_devmap_lock); | ||
| 704 | if (val) | ||
| 705 | devmap->features |= DASD_FEATURE_FAILFAST; | ||
| 706 | else | ||
| 707 | devmap->features &= ~DASD_FEATURE_FAILFAST; | ||
| 708 | if (devmap->device) | ||
| 709 | devmap->device->features = devmap->features; | ||
| 710 | spin_unlock(&dasd_devmap_lock); | ||
| 711 | return count; | ||
| 712 | } | ||
| 713 | |||
| 714 | static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store); | ||
| 715 | |||
| 716 | /* | ||
| 670 | * readonly controls the readonly status of a dasd | 717 | * readonly controls the readonly status of a dasd |
| 671 | */ | 718 | */ |
| 672 | static ssize_t | 719 | static ssize_t |
| @@ -1020,6 +1067,7 @@ static struct attribute * dasd_attrs[] = { | |||
| 1020 | &dev_attr_use_diag.attr, | 1067 | &dev_attr_use_diag.attr, |
| 1021 | &dev_attr_eer_enabled.attr, | 1068 | &dev_attr_eer_enabled.attr, |
| 1022 | &dev_attr_erplog.attr, | 1069 | &dev_attr_erplog.attr, |
| 1070 | &dev_attr_failfast.attr, | ||
| 1023 | NULL, | 1071 | NULL, |
| 1024 | }; | 1072 | }; |
| 1025 | 1073 | ||
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 7844461a995b..ef2a56952054 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
| @@ -544,7 +544,8 @@ 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 (blk_noretry_request(req)) | 547 | if (blk_noretry_request(req) || |
| 548 | block->base->features & DASD_FEATURE_FAILFAST) | ||
| 548 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 549 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
| 549 | cqr->startdev = memdev; | 550 | cqr->startdev = memdev; |
| 550 | cqr->memdev = memdev; | 551 | cqr->memdev = memdev; |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index bd2c52e20762..bdb87998f364 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
| @@ -1700,7 +1700,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, | |||
| 1700 | recid++; | 1700 | recid++; |
| 1701 | } | 1701 | } |
| 1702 | } | 1702 | } |
| 1703 | if (blk_noretry_request(req)) | 1703 | if (blk_noretry_request(req) || |
| 1704 | block->base->features & DASD_FEATURE_FAILFAST) | ||
| 1704 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 1705 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
| 1705 | cqr->startdev = startdev; | 1706 | cqr->startdev = startdev; |
| 1706 | cqr->memdev = startdev; | 1707 | cqr->memdev = startdev; |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 7d442aeff3d1..f1d176021694 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
| @@ -355,7 +355,8 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, | |||
| 355 | recid++; | 355 | recid++; |
| 356 | } | 356 | } |
| 357 | } | 357 | } |
| 358 | if (blk_noretry_request(req)) | 358 | if (blk_noretry_request(req) || |
| 359 | block->base->features & DASD_FEATURE_FAILFAST) | ||
| 359 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); | 360 | set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); |
| 360 | cqr->startdev = memdev; | 361 | cqr->startdev = memdev; |
| 361 | cqr->memdev = memdev; | 362 | cqr->memdev = memdev; |
