diff options
author | Jan Höppner <hoeppner@linux.ibm.com> | 2020-10-08 16:13:32 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-11-16 18:14:38 +0300 |
commit | 460181217a2496defc6c279b0a7eb810b05b9145 (patch) | |
tree | 93471bca91b533034347070c56218350abe1fb47 /drivers/s390/block | |
parent | d2a527580c0a0c83f1d98eff32804cde4280d721 (diff) | |
download | linux-460181217a2496defc6c279b0a7eb810b05b9145.tar.xz |
s390/dasd: Store path configuration data during path handling
Currently, the configuration data for a path is retrieved during a path
verification and used only temporarily. If a path is newly added to the
I/O setup after a boot, no configuration data will be stored for this
particular path.
However, this data is required for later use and should be present for
a valid I/O path anyway. Store this data during the path verification so
that newly added paths can provide all information necessary.
[sth@linux.ibm.com: fix conf_data memleak]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/s390/block')
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 497aa81778b6..3ff7b532a5bf 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1007,6 +1007,11 @@ static void dasd_eckd_store_conf_data(struct dasd_device *device, struct subchannel_id sch_id; ccw_device_get_schid(device->cdev, &sch_id); + /* + * path handling and read_conf allocate data + * free it before replacing the pointer + */ + kfree(device->path[chp].conf_data); device->path[chp].conf_data = conf_data; device->path[chp].cssid = sch_id.cssid; device->path[chp].ssid = sch_id.ssid; @@ -1263,9 +1268,10 @@ static void do_path_verification_work(struct work_struct *work) struct dasd_uid *uid; __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; __u8 lpm, opm, npm, ppm, epm, hpfpm, cablepm; + struct dasd_conf_data *conf_data; unsigned long flags; char print_uid[60]; - int rc; + int rc, pos; data = container_of(work, struct path_verification_work_data, worker); device = data->device; @@ -1395,6 +1401,14 @@ static void do_path_verification_work(struct work_struct *work) } } + conf_data = kzalloc(DASD_ECKD_RCD_DATA_SIZE, GFP_KERNEL); + if (conf_data) { + memcpy(conf_data, data->rcd_buffer, + DASD_ECKD_RCD_DATA_SIZE); + } + pos = pathmask_to_pos(lpm); + dasd_eckd_store_conf_data(device, conf_data, pos); + /* * There is a small chance that a path is lost again between * above path verification and the following modification of |