Merge tag 'for-5.15/io_uring-vfs-2021-08-30' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / drivers / s390 / block / dasd_eckd.c
index 0de1a46..460e0f1 100644 (file)
@@ -1004,15 +1004,23 @@ static unsigned char dasd_eckd_path_access(void *conf_data, int conf_len)
 static void dasd_eckd_store_conf_data(struct dasd_device *device,
                                      struct dasd_conf_data *conf_data, int chp)
 {
+       struct dasd_eckd_private *private = device->private;
        struct channel_path_desc_fmt0 *chp_desc;
        struct subchannel_id sch_id;
+       void *cdp;
 
-       ccw_device_get_schid(device->cdev, &sch_id);
        /*
         * path handling and read_conf allocate data
         * free it before replacing the pointer
+        * also replace the old private->conf_data pointer
+        * with the new one if this points to the same data
         */
-       kfree(device->path[chp].conf_data);
+       cdp = device->path[chp].conf_data;
+       if (private->conf_data == cdp) {
+               private->conf_data = (void *)conf_data;
+               dasd_eckd_identify_conf_parts(private);
+       }
+       ccw_device_get_schid(device->cdev, &sch_id);
        device->path[chp].conf_data = conf_data;
        device->path[chp].cssid = sch_id.cssid;
        device->path[chp].ssid = sch_id.ssid;
@@ -1020,6 +1028,7 @@ static void dasd_eckd_store_conf_data(struct dasd_device *device,
        if (chp_desc)
                device->path[chp].chpid = chp_desc->chpid;
        kfree(chp_desc);
+       kfree(cdp);
 }
 
 static void dasd_eckd_clear_conf_data(struct dasd_device *device)
@@ -3267,7 +3276,7 @@ static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb)
        end_blk = (curr_trk + 1) * recs_per_trk;
 
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv.bv_page) + bv.bv_offset;
+               dst = bvec_virt(&bv);
                for (off = 0; off < bv.bv_len; off += blksize) {
                        if (first_blk + blk_count >= end_blk) {
                                cqr->proc_bytes = blk_count * blksize;
@@ -3999,7 +4008,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
                              last_rec - recid + 1, cmd, basedev, blksize);
        }
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv.bv_page) + bv.bv_offset;
+               dst = bvec_virt(&bv);
                if (dasd_page_cache) {
                        char *copy = kmem_cache_alloc(dasd_page_cache,
                                                      GFP_DMA | __GFP_NOWARN);
@@ -4166,7 +4175,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
        idaw_dst = NULL;
        idaw_len = 0;
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv.bv_page) + bv.bv_offset;
+               dst = bvec_virt(&bv);
                seg_len = bv.bv_len;
                while (seg_len) {
                        if (new_track) {
@@ -4509,7 +4518,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                new_track = 1;
                recid = first_rec;
                rq_for_each_segment(bv, req, iter) {
-                       dst = page_address(bv.bv_page) + bv.bv_offset;
+                       dst = bvec_virt(&bv);
                        seg_len = bv.bv_len;
                        while (seg_len) {
                                if (new_track) {
@@ -4542,7 +4551,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
                }
        } else {
                rq_for_each_segment(bv, req, iter) {
-                       dst = page_address(bv.bv_page) + bv.bv_offset;
+                       dst = bvec_virt(&bv);
                        last_tidaw = itcw_add_tidaw(itcw, 0x00,
                                                    dst, bv.bv_len);
                        if (IS_ERR(last_tidaw)) {
@@ -4778,7 +4787,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
                        idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);
        }
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv.bv_page) + bv.bv_offset;
+               dst = bvec_virt(&bv);
                seg_len = bv.bv_len;
                if (cmd == DASD_ECKD_CCW_READ_TRACK)
                        memset(dst, 0, seg_len);
@@ -4839,7 +4848,7 @@ dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
        if (private->uses_cdl == 0 || recid > 2*blk_per_trk)
                ccw++;
        rq_for_each_segment(bv, req, iter) {
-               dst = page_address(bv.bv_page) + bv.bv_offset;
+               dst = bvec_virt(&bv);
                for (off = 0; off < bv.bv_len; off += blksize) {
                        /* Skip locate record. */
                        if (private->uses_cdl && recid <= 2*blk_per_trk)