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

s390/dasd: Move device name formatting into separate function

The device name formatting can be generalized and made more readable
compared to the current state. SCSI already provides a generalized way
to format many devices in the same naming scheme as DASD does, which was
introduced with commit 3e1a7ff8a0a7 ("block: allow disk to have extended
device number").

Use this much cleaner code from drivers/scsi/sd.c to handle the legacy
naming scheme in DASD as a replacement for the current implementation.

For easier error handling for the new function, move the gendisk free
portion of dasd_gendisk_free() out into a new function dasd_gd_free().

Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Jan Höppner and committed by
Jens Axboe
43198756 764def9e

+54 -26
+54 -26
drivers/s390/block/dasd_genhd.c
··· 22 22 23 23 static unsigned int queue_depth = 32; 24 24 static unsigned int nr_hw_queues = 4; 25 + static void dasd_gd_free(struct gendisk *gdp); 25 26 26 27 module_param(queue_depth, uint, 0444); 27 28 MODULE_PARM_DESC(queue_depth, "Default queue depth for new DASD devices"); 28 29 29 30 module_param(nr_hw_queues, uint, 0444); 30 31 MODULE_PARM_DESC(nr_hw_queues, "Default number of hardware queues for new DASD devices"); 32 + 33 + /* 34 + * Set device name. 35 + * dasda - dasdz : 26 devices 36 + * dasdaa - dasdzz : 676 devices, added up = 702 37 + * dasdaaa - dasdzzz : 17576 devices, added up = 18278 38 + * dasdaaaa - dasdzzzz : 456976 devices, added up = 475252 39 + */ 40 + static int dasd_name_format(char *prefix, int index, char *buf, int buflen) 41 + { 42 + const int base = 'z' - 'a' + 1; 43 + char *begin = buf + strlen(prefix); 44 + char *end = buf + buflen; 45 + char *p; 46 + int unit; 47 + 48 + p = end - 1; 49 + *p = '\0'; 50 + unit = base; 51 + do { 52 + if (p == begin) 53 + return -EINVAL; 54 + *--p = 'a' + (index % unit); 55 + index = (index / unit) - 1; 56 + } while (index >= 0); 57 + 58 + memmove(begin, p, end - p); 59 + memcpy(buf, prefix, strlen(prefix)); 60 + 61 + return 0; 62 + } 31 63 32 64 /* 33 65 * Allocate and register gendisk structure for device. ··· 77 45 }; 78 46 struct gendisk *gdp; 79 47 struct dasd_device *base; 80 - int len, rc; 48 + unsigned int devindex; 49 + int rc; 81 50 82 51 /* Make sure the minor for this device exists. */ 83 52 base = block->base; 84 - if (base->devindex >= DASD_PER_MAJOR) 53 + devindex = base->devindex; 54 + if (devindex >= DASD_PER_MAJOR) 85 55 return -EBUSY; 86 56 87 57 block->tag_set.ops = &dasd_mq_ops; ··· 103 69 104 70 /* Initialize gendisk structure. */ 105 71 gdp->major = DASD_MAJOR; 106 - gdp->first_minor = base->devindex << DASD_PARTN_BITS; 72 + gdp->first_minor = devindex << DASD_PARTN_BITS; 107 73 gdp->minors = 1 << DASD_PARTN_BITS; 108 74 gdp->fops = &dasd_device_operations; 109 75 110 - /* 111 - * Set device name. 112 - * dasda - dasdz : 26 devices 113 - * dasdaa - dasdzz : 676 devices, added up = 702 114 - * dasdaaa - dasdzzz : 17576 devices, added up = 18278 115 - * dasdaaaa - dasdzzzz : 456976 devices, added up = 475252 116 - */ 117 - len = sprintf(gdp->disk_name, "dasd"); 118 - if (base->devindex > 25) { 119 - if (base->devindex > 701) { 120 - if (base->devindex > 18277) 121 - len += sprintf(gdp->disk_name + len, "%c", 122 - 'a'+(((base->devindex-18278) 123 - /17576)%26)); 124 - len += sprintf(gdp->disk_name + len, "%c", 125 - 'a'+(((base->devindex-702)/676)%26)); 126 - } 127 - len += sprintf(gdp->disk_name + len, "%c", 128 - 'a'+(((base->devindex-26)/26)%26)); 76 + rc = dasd_name_format("dasd", devindex, gdp->disk_name, sizeof(gdp->disk_name)); 77 + if (rc) { 78 + DBF_DEV_EVENT(DBF_ERR, block->base, 79 + "setting disk name failed, rc %d", rc); 80 + dasd_gd_free(gdp); 81 + return rc; 129 82 } 130 - len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); 131 83 132 84 if (base->features & DASD_FEATURE_READONLY || 133 85 test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) ··· 132 112 } 133 113 134 114 /* 115 + * Free gendisk structure 116 + */ 117 + static void dasd_gd_free(struct gendisk *gd) 118 + { 119 + del_gendisk(gd); 120 + gd->private_data = NULL; 121 + put_disk(gd); 122 + } 123 + 124 + /* 135 125 * Unregister and free gendisk structure for device. 136 126 */ 137 127 void dasd_gendisk_free(struct dasd_block *block) 138 128 { 139 129 if (block->gdp) { 140 - del_gendisk(block->gdp); 141 - block->gdp->private_data = NULL; 142 - put_disk(block->gdp); 130 + dasd_gd_free(block->gdp); 143 131 block->gdp = NULL; 144 132 blk_mq_free_tag_set(&block->tag_set); 145 133 }