diff options
author | Stefan Haberland <stefan.haberland@de.ibm.com> | 2012-11-28 13:43:38 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-11-30 15:40:44 +0100 |
commit | d07dc5d8ab6f15353c866e2768c389abdc1faba6 (patch) | |
tree | 9ecf558a0e3d128534b56200b0f411aab315fc0f /drivers/s390/block/dasd_devmap.c | |
parent | 55d3a85cd2fa3274a6dfa0901a3be342b433bfa0 (diff) | |
download | linux-stable-d07dc5d8ab6f15353c866e2768c389abdc1faba6.tar.gz linux-stable-d07dc5d8ab6f15353c866e2768c389abdc1faba6.tar.bz2 linux-stable-d07dc5d8ab6f15353c866e2768c389abdc1faba6.zip |
s390/dasd: add safe offline interface
The regular behavior of the DASD device driver when setting a device
offline is to return all outstanding I/O as failed. This behavior is
different from that of other System z operating systems and may lead
to unexpected data loss. Adding an explicit 'safe' offline function
will allow customers to use DASDs in the way they expect them to work.
Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index b2b8c18eeced..4d12370337aa 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -952,6 +952,39 @@ static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show, dasd_use_raw_store); static ssize_t +dasd_safe_offline_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ccw_device *cdev = to_ccwdev(dev); + struct dasd_device *device; + int rc; + + device = dasd_device_from_cdev(cdev); + if (IS_ERR(device)) { + rc = PTR_ERR(device); + goto out; + } + + if (test_bit(DASD_FLAG_OFFLINE, &device->flags) || + test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { + /* Already doing offline processing */ + dasd_put_device(device); + rc = -EBUSY; + goto out; + } + + set_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags); + dasd_put_device(device); + + rc = ccw_device_set_offline(cdev); + +out: + return rc ? rc : count; +} + +static DEVICE_ATTR(safe_offline, 0200, NULL, dasd_safe_offline_store); + +static ssize_t dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1320,6 +1353,7 @@ static struct attribute * dasd_attrs[] = { &dev_attr_expires.attr, &dev_attr_reservation_policy.attr, &dev_attr_last_known_reservation_state.attr, + &dev_attr_safe_offline.attr, NULL, }; |