From d07dc5d8ab6f15353c866e2768c389abdc1faba6 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Wed, 28 Nov 2012 13:43:38 +0100 Subject: 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 Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd_devmap.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/s390/block/dasd_devmap.c') diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index b2b8c18eece..4d12370337a 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -951,6 +951,39 @@ dasd_use_raw_store(struct device *dev, struct device_attribute *attr, 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, }; -- cgit v1.2.3-70-g09d2