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; |