Jiri Slaby c5b460
From: Stefan Haberland <sth@linux.ibm.com>
Jiri Slaby c5b460
Date: Fri, 19 May 2023 12:23:40 +0200
Jiri Slaby c5b460
Subject: [PATCH] s390/dasd: fix command reject error on ESE devices
Jiri Slaby c5b460
References: bsc#1012628
Jiri Slaby c5b460
Patch-mainline: 6.3.4
Jiri Slaby c5b460
Git-commit: c99bff34290f1b994073557b754aff86e4c7b22e
Jiri Slaby c5b460
Jiri Slaby c5b460
commit c99bff34290f1b994073557b754aff86e4c7b22e upstream.
Jiri Slaby c5b460
Jiri Slaby c5b460
Formatting a thin-provisioned (ESE) device that is part of a PPRC copy
Jiri Slaby c5b460
relation might fail with the following error:
Jiri Slaby c5b460
Jiri Slaby c5b460
dasd-eckd 0.0.f500: An error occurred in the DASD device driver, reason=09
Jiri Slaby c5b460
[...]
Jiri Slaby c5b460
24 Byte: 0 MSG 4, no MSGb to SYSOP
Jiri Slaby c5b460
Jiri Slaby c5b460
During format of an ESE disk the Release Allocated Space command is used.
Jiri Slaby c5b460
A bit in the payload of the command is set that is not allowed to be set
Jiri Slaby c5b460
for devices in a copy relation. This bit is set to allow the partial
Jiri Slaby c5b460
release of an extent.
Jiri Slaby c5b460
Jiri Slaby c5b460
Check for the existence of a copy relation before setting the respective
Jiri Slaby c5b460
bit.
Jiri Slaby c5b460
Jiri Slaby c5b460
Fixes: 91dc4a197569 ("s390/dasd: Add new ioctl to release space")
Jiri Slaby c5b460
Cc: stable@kernel.org # 5.3+
Jiri Slaby c5b460
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Jiri Slaby c5b460
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Jiri Slaby c5b460
Link: https://lore.kernel.org/r/20230519102340.3854819-2-sth@linux.ibm.com
Jiri Slaby c5b460
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Jiri Slaby c5b460
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Jiri Slaby c5b460
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby c5b460
---
Jiri Slaby c5b460
 drivers/s390/block/dasd_eckd.c | 33 +++++++++++++++++++++++++++++++--
Jiri Slaby c5b460
 1 file changed, 31 insertions(+), 2 deletions(-)
Jiri Slaby c5b460
Jiri Slaby c5b460
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
Jiri Slaby c5b460
index 1a69f97e..1baf548c 100644
Jiri Slaby c5b460
--- a/drivers/s390/block/dasd_eckd.c
Jiri Slaby c5b460
+++ b/drivers/s390/block/dasd_eckd.c
Jiri Slaby c5b460
@@ -127,6 +127,8 @@ static int prepare_itcw(struct itcw *, unsigned int, unsigned int, int,
Jiri Slaby c5b460
 			struct dasd_device *, struct dasd_device *,
Jiri Slaby c5b460
 			unsigned int, int, unsigned int, unsigned int,
Jiri Slaby c5b460
 			unsigned int, unsigned int);
Jiri Slaby c5b460
+static int dasd_eckd_query_pprc_status(struct dasd_device *,
Jiri Slaby c5b460
+				       struct dasd_pprc_data_sc4 *);
Jiri Slaby c5b460
 
Jiri Slaby c5b460
 /* initial attempt at a probe function. this can be simplified once
Jiri Slaby c5b460
  * the other detection code is gone */
Jiri Slaby c5b460
@@ -3732,6 +3734,26 @@ static int count_exts(unsigned int from, unsigned int to, int trks_per_ext)
Jiri Slaby c5b460
 	return count;
Jiri Slaby c5b460
 }
Jiri Slaby c5b460
 
Jiri Slaby c5b460
+static int dasd_in_copy_relation(struct dasd_device *device)
Jiri Slaby c5b460
+{
Jiri Slaby c5b460
+	struct dasd_pprc_data_sc4 *temp;
Jiri Slaby c5b460
+	int rc;
Jiri Slaby c5b460
+
Jiri Slaby c5b460
+	if (!dasd_eckd_pprc_enabled(device))
Jiri Slaby c5b460
+		return 0;
Jiri Slaby c5b460
+
Jiri Slaby c5b460
+	temp = kzalloc(sizeof(*temp), GFP_KERNEL);
Jiri Slaby c5b460
+	if (!temp)
Jiri Slaby c5b460
+		return -ENOMEM;
Jiri Slaby c5b460
+
Jiri Slaby c5b460
+	rc = dasd_eckd_query_pprc_status(device, temp);
Jiri Slaby c5b460
+	if (!rc)
Jiri Slaby c5b460
+		rc = temp->dev_info[0].state;
Jiri Slaby c5b460
+
Jiri Slaby c5b460
+	kfree(temp);
Jiri Slaby c5b460
+	return rc;
Jiri Slaby c5b460
+}
Jiri Slaby c5b460
+
Jiri Slaby c5b460
 /*
Jiri Slaby c5b460
  * Release allocated space for a given range or an entire volume.
Jiri Slaby c5b460
  */
Jiri Slaby c5b460
@@ -3748,6 +3770,7 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
Jiri Slaby c5b460
 	int cur_to_trk, cur_from_trk;
Jiri Slaby c5b460
 	struct dasd_ccw_req *cqr;
Jiri Slaby c5b460
 	u32 beg_cyl, end_cyl;
Jiri Slaby c5b460
+	int copy_relation;
Jiri Slaby c5b460
 	struct ccw1 *ccw;
Jiri Slaby c5b460
 	int trks_per_ext;
Jiri Slaby c5b460
 	size_t ras_size;
Jiri Slaby c5b460
@@ -3759,6 +3782,10 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
Jiri Slaby c5b460
 	if (dasd_eckd_ras_sanity_checks(device, first_trk, last_trk))
Jiri Slaby c5b460
 		return ERR_PTR(-EINVAL);
Jiri Slaby c5b460
 
Jiri Slaby c5b460
+	copy_relation = dasd_in_copy_relation(device);
Jiri Slaby c5b460
+	if (copy_relation < 0)
Jiri Slaby c5b460
+		return ERR_PTR(copy_relation);
Jiri Slaby c5b460
+
Jiri Slaby c5b460
 	rq = req ? blk_mq_rq_to_pdu(req) : NULL;
Jiri Slaby c5b460
 
Jiri Slaby c5b460
 	features = &private->features;
Jiri Slaby c5b460
@@ -3787,9 +3814,11 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
Jiri Slaby c5b460
 	/*
Jiri Slaby c5b460
 	 * This bit guarantees initialisation of tracks within an extent that is
Jiri Slaby c5b460
 	 * not fully specified, but is only supported with a certain feature
Jiri Slaby c5b460
-	 * subset.
Jiri Slaby c5b460
+	 * subset and for devices not in a copy relation.
Jiri Slaby c5b460
 	 */
Jiri Slaby c5b460
-	ras_data->op_flags.guarantee_init = !!(features->feature[56] & 0x01);
Jiri Slaby c5b460
+	if (features->feature[56] & 0x01 && !copy_relation)
Jiri Slaby c5b460
+		ras_data->op_flags.guarantee_init = 1;
Jiri Slaby c5b460
+
Jiri Slaby c5b460
 	ras_data->lss = private->conf.ned->ID;
Jiri Slaby c5b460
 	ras_data->dev_addr = private->conf.ned->unit_addr;
Jiri Slaby c5b460
 	ras_data->nr_exts = nr_exts;
Jiri Slaby c5b460
-- 
Jiri Slaby c5b460
2.35.3
Jiri Slaby c5b460