Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Holger Smolinski and committed by
Martin Schwidefsky
13de227b 1301809b

+55 -3
+1
arch/s390/include/asm/dasd.h
··· 78 78 #define DASD_FEATURE_USEDIAG 0x02 79 79 #define DASD_FEATURE_INITIAL_ONLINE 0x04 80 80 #define DASD_FEATURE_ERPLOG 0x08 81 + #define DASD_FEATURE_FAILFAST 0x10 81 82 82 83 #define DASD_PARTN_BITS 2 83 84
+48
drivers/s390/block/dasd_devmap.c
··· 206 206 features |= DASD_FEATURE_USEDIAG; 207 207 else if (len == 6 && !strncmp(str, "erplog", 6)) 208 208 features |= DASD_FEATURE_ERPLOG; 209 + else if (len == 8 && !strncmp(str, "failfast", 8)) 210 + features |= DASD_FEATURE_FAILFAST; 209 211 else { 210 212 MESSAGE(KERN_WARNING, 211 213 "unsupported feature: %*s, " ··· 669 667 */ 670 668 671 669 /* 670 + * failfast controls the behaviour, if no path is available 671 + */ 672 + static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr, 673 + char *buf) 674 + { 675 + struct dasd_devmap *devmap; 676 + int ff_flag; 677 + 678 + devmap = dasd_find_busid(dev->bus_id); 679 + if (!IS_ERR(devmap)) 680 + ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0; 681 + else 682 + ff_flag = (DASD_FEATURE_DEFAULT & DASD_FEATURE_FAILFAST) != 0; 683 + return snprintf(buf, PAGE_SIZE, ff_flag ? "1\n" : "0\n"); 684 + } 685 + 686 + static ssize_t dasd_ff_store(struct device *dev, struct device_attribute *attr, 687 + const char *buf, size_t count) 688 + { 689 + struct dasd_devmap *devmap; 690 + int val; 691 + char *endp; 692 + 693 + devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 694 + if (IS_ERR(devmap)) 695 + return PTR_ERR(devmap); 696 + 697 + val = simple_strtoul(buf, &endp, 0); 698 + if (((endp + 1) < (buf + count)) || (val > 1)) 699 + return -EINVAL; 700 + 701 + spin_lock(&dasd_devmap_lock); 702 + if (val) 703 + devmap->features |= DASD_FEATURE_FAILFAST; 704 + else 705 + devmap->features &= ~DASD_FEATURE_FAILFAST; 706 + if (devmap->device) 707 + devmap->device->features = devmap->features; 708 + spin_unlock(&dasd_devmap_lock); 709 + return count; 710 + } 711 + 712 + static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store); 713 + 714 + /* 672 715 * readonly controls the readonly status of a dasd 673 716 */ 674 717 static ssize_t ··· 1067 1020 &dev_attr_use_diag.attr, 1068 1021 &dev_attr_eer_enabled.attr, 1069 1022 &dev_attr_erplog.attr, 1023 + &dev_attr_failfast.attr, 1070 1024 NULL, 1071 1025 }; 1072 1026
+2 -1
drivers/s390/block/dasd_diag.c
··· 544 544 } 545 545 cqr->retries = DIAG_MAX_RETRIES; 546 546 cqr->buildclk = get_clock(); 547 - if (blk_noretry_request(req)) 547 + if (blk_noretry_request(req) || 548 + block->base->features & DASD_FEATURE_FAILFAST) 548 549 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 549 550 cqr->startdev = memdev; 550 551 cqr->memdev = memdev;
+2 -1
drivers/s390/block/dasd_eckd.c
··· 1700 1700 recid++; 1701 1701 } 1702 1702 } 1703 - if (blk_noretry_request(req)) 1703 + if (blk_noretry_request(req) || 1704 + block->base->features & DASD_FEATURE_FAILFAST) 1704 1705 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1705 1706 cqr->startdev = startdev; 1706 1707 cqr->memdev = startdev;
+2 -1
drivers/s390/block/dasd_fba.c
··· 355 355 recid++; 356 356 } 357 357 } 358 - if (blk_noretry_request(req)) 358 + if (blk_noretry_request(req) || 359 + block->base->features & DASD_FEATURE_FAILFAST) 359 360 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 360 361 cqr->startdev = memdev; 361 362 cqr->memdev = memdev;