[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>
This commit is contained in:
parent
1301809bce
commit
13de227bcd
5 changed files with 55 additions and 3 deletions
|
@ -78,6 +78,7 @@ typedef struct dasd_information2_t {
|
|||
#define DASD_FEATURE_USEDIAG 0x02
|
||||
#define DASD_FEATURE_INITIAL_ONLINE 0x04
|
||||
#define DASD_FEATURE_ERPLOG 0x08
|
||||
#define DASD_FEATURE_FAILFAST 0x10
|
||||
|
||||
#define DASD_PARTN_BITS 2
|
||||
|
||||
|
|
|
@ -206,6 +206,8 @@ dasd_feature_list(char *str, char **endp)
|
|||
features |= DASD_FEATURE_USEDIAG;
|
||||
else if (len == 6 && !strncmp(str, "erplog", 6))
|
||||
features |= DASD_FEATURE_ERPLOG;
|
||||
else if (len == 8 && !strncmp(str, "failfast", 8))
|
||||
features |= DASD_FEATURE_FAILFAST;
|
||||
else {
|
||||
MESSAGE(KERN_WARNING,
|
||||
"unsupported feature: %*s, "
|
||||
|
@ -666,6 +668,51 @@ dasd_device_from_cdev(struct ccw_device *cdev)
|
|||
* 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
|
||||
*/
|
||||
|
@ -1020,6 +1067,7 @@ static struct attribute * dasd_attrs[] = {
|
|||
&dev_attr_use_diag.attr,
|
||||
&dev_attr_eer_enabled.attr,
|
||||
&dev_attr_erplog.attr,
|
||||
&dev_attr_failfast.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
@ -544,7 +544,8 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
|
|||
}
|
||||
cqr->retries = DIAG_MAX_RETRIES;
|
||||
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);
|
||||
cqr->startdev = memdev;
|
||||
cqr->memdev = memdev;
|
||||
|
|
|
@ -1700,7 +1700,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
|
|||
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);
|
||||
cqr->startdev = startdev;
|
||||
cqr->memdev = startdev;
|
||||
|
|
|
@ -355,7 +355,8 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
|
|||
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);
|
||||
cqr->startdev = memdev;
|
||||
cqr->memdev = memdev;
|
||||
|
|
Loading…
Reference in a new issue