diff options
author | Stefan Weinhuber <wein@de.ibm.com> | 2011-01-05 12:48:04 +0100 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2011-01-05 12:47:30 +0100 |
commit | 5a27e60dec59a95bd7f8ae9a19ae2ede4f76395b (patch) | |
tree | 20595cba0caebf7a8a5f0afac9785c7d717f3e8c /drivers/s390/block/dasd_devmap.c | |
parent | a4d26c6aeceea330ee5e0fb6b017d57e3b252d29 (diff) |
[S390] dasd: Improve handling of stolen DASD reservation
If a DASD device has been reserved by a Linux system, and later
this reservation is ‘stolen’ by a second system by means of an
unconditional reserve, then the first system receives a
notification about this fact. With this patch such an event can
be either ignored, as before, or it can be used to let the device
fail all I/O request, so that the device will not block anymore.
Signed-off-by: Stefan Weinhuber <wein@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 | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 0001df8ad3e..47fc8869249 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -1127,6 +1127,103 @@ dasd_expires_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); +static ssize_t dasd_reservation_policy_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct dasd_devmap *devmap; + int rc = 0; + + devmap = dasd_find_busid(dev_name(dev)); + if (IS_ERR(devmap)) { + rc = snprintf(buf, PAGE_SIZE, "ignore\n"); + } else { + spin_lock(&dasd_devmap_lock); + if (devmap->features & DASD_FEATURE_FAILONSLCK) + rc = snprintf(buf, PAGE_SIZE, "fail\n"); + else + rc = snprintf(buf, PAGE_SIZE, "ignore\n"); + spin_unlock(&dasd_devmap_lock); + } + return rc; +} + +static ssize_t dasd_reservation_policy_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dasd_devmap *devmap; + int rc; + + devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); + if (IS_ERR(devmap)) + return PTR_ERR(devmap); + rc = 0; + spin_lock(&dasd_devmap_lock); + if (sysfs_streq("ignore", buf)) + devmap->features &= ~DASD_FEATURE_FAILONSLCK; + else if (sysfs_streq("fail", buf)) + devmap->features |= DASD_FEATURE_FAILONSLCK; + else + rc = -EINVAL; + if (devmap->device) + devmap->device->features = devmap->features; + spin_unlock(&dasd_devmap_lock); + if (rc) + return rc; + else + return count; +} + +static DEVICE_ATTR(reservation_policy, 0644, + dasd_reservation_policy_show, dasd_reservation_policy_store); + +static ssize_t dasd_reservation_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct dasd_device *device; + int rc = 0; + + device = dasd_device_from_cdev(to_ccwdev(dev)); + if (IS_ERR(device)) + return snprintf(buf, PAGE_SIZE, "none\n"); + + if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) + rc = snprintf(buf, PAGE_SIZE, "reserved\n"); + else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags)) + rc = snprintf(buf, PAGE_SIZE, "lost\n"); + else + rc = snprintf(buf, PAGE_SIZE, "none\n"); + dasd_put_device(device); + return rc; +} + +static ssize_t dasd_reservation_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dasd_device *device; + int rc = 0; + + device = dasd_device_from_cdev(to_ccwdev(dev)); + if (IS_ERR(device)) + return -ENODEV; + if (sysfs_streq("reset", buf)) + clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags); + else + rc = -EINVAL; + dasd_put_device(device); + + if (rc) + return rc; + else + return count; +} + +static DEVICE_ATTR(last_known_reservation_state, 0644, + dasd_reservation_state_show, dasd_reservation_state_store); + static struct attribute * dasd_attrs[] = { &dev_attr_readonly.attr, &dev_attr_discipline.attr, @@ -1139,6 +1236,8 @@ static struct attribute * dasd_attrs[] = { &dev_attr_erplog.attr, &dev_attr_failfast.attr, &dev_attr_expires.attr, + &dev_attr_reservation_policy.attr, + &dev_attr_last_known_reservation_state.attr, NULL, }; |