Commit 13de227b authored by Holger Smolinski's avatar Holger Smolinski Committed by Martin Schwidefsky

[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: default avatarHolger Smolinski <Holger.Smolinski@de.ibm.com>
Signed-off-by: default avatarStefan Weinhuber <wein@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 1301809b
...@@ -78,6 +78,7 @@ typedef struct dasd_information2_t { ...@@ -78,6 +78,7 @@ typedef struct dasd_information2_t {
#define DASD_FEATURE_USEDIAG 0x02 #define DASD_FEATURE_USEDIAG 0x02
#define DASD_FEATURE_INITIAL_ONLINE 0x04 #define DASD_FEATURE_INITIAL_ONLINE 0x04
#define DASD_FEATURE_ERPLOG 0x08 #define DASD_FEATURE_ERPLOG 0x08
#define DASD_FEATURE_FAILFAST 0x10
#define DASD_PARTN_BITS 2 #define DASD_PARTN_BITS 2
......
...@@ -206,6 +206,8 @@ dasd_feature_list(char *str, char **endp) ...@@ -206,6 +206,8 @@ dasd_feature_list(char *str, char **endp)
features |= DASD_FEATURE_USEDIAG; features |= DASD_FEATURE_USEDIAG;
else if (len == 6 && !strncmp(str, "erplog", 6)) else if (len == 6 && !strncmp(str, "erplog", 6))
features |= DASD_FEATURE_ERPLOG; features |= DASD_FEATURE_ERPLOG;
else if (len == 8 && !strncmp(str, "failfast", 8))
features |= DASD_FEATURE_FAILFAST;
else { else {
MESSAGE(KERN_WARNING, MESSAGE(KERN_WARNING,
"unsupported feature: %*s, " "unsupported feature: %*s, "
...@@ -666,6 +668,51 @@ dasd_device_from_cdev(struct ccw_device *cdev) ...@@ -666,6 +668,51 @@ dasd_device_from_cdev(struct ccw_device *cdev)
* SECTION: files in sysfs * SECTION: files in sysfs
*/ */
/*
* failfast controls the behaviour, if no path is available
*/
static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct dasd_devmap *devmap;
int ff_flag;
devmap = dasd_find_busid(dev->bus_id);
if (!IS_ERR(devmap))
ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
else
ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0;
return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n");
}
static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dasd_devmap *devmap;
int val;
char *endp;
devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
if (IS_ERR(devmap))
return PTR_ERR(devmap);
val = simple_strtoul(buf, &endp, 0);
if (((endp + 1) < (buf + count)) || (val > 1))
return -EINVAL;
spin_lock(&dasd_devmap_lock);
if (val)
devmap->features |= DASD_FEATURE_FAILFAST;
else
devmap->features &= ~DASD_FEATURE_FAILFAST;
if (devmap->device)
devmap->device->features = devmap->features;
spin_unlock(&dasd_devmap_lock);
return count;
}
static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store);
/* /*
* readonly controls the readonly status of a dasd * readonly controls the readonly status of a dasd
*/ */
...@@ -1020,6 +1067,7 @@ static struct attribute * dasd_attrs[] = { ...@@ -1020,6 +1067,7 @@ static struct attribute * dasd_attrs[] = {
&dev_attr_use_diag.attr, &dev_attr_use_diag.attr,
&dev_attr_eer_enabled.attr, &dev_attr_eer_enabled.attr,
&dev_attr_erplog.attr, &dev_attr_erplog.attr,
&dev_attr_failfast.attr,
NULL, NULL,
}; };
......
...@@ -544,7 +544,8 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev, ...@@ -544,7 +544,8 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
} }
cqr->retries = DIAG_MAX_RETRIES; cqr->retries = DIAG_MAX_RETRIES;
cqr->buildclk = get_clock(); cqr->buildclk = get_clock();
if (blk_noretry_request(req)) if (blk_noretry_request(req) ||
block->base->features & DASD_FEATURE_FAILFAST)
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->startdev = memdev; cqr->startdev = memdev;
cqr->memdev = memdev; cqr->memdev = memdev;
......
...@@ -1700,7 +1700,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, ...@@ -1700,7 +1700,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
recid++; recid++;
} }
} }
if (blk_noretry_request(req)) if (blk_noretry_request(req) ||
block->base->features & DASD_FEATURE_FAILFAST)
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->startdev = startdev; cqr->startdev = startdev;
cqr->memdev = startdev; cqr->memdev = startdev;
......
...@@ -355,7 +355,8 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, ...@@ -355,7 +355,8 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
recid++; recid++;
} }
} }
if (blk_noretry_request(req)) if (blk_noretry_request(req) ||
block->base->features & DASD_FEATURE_FAILFAST)
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->startdev = memdev; cqr->startdev = memdev;
cqr->memdev = memdev; cqr->memdev = memdev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment