Skip to content

Commit c99bff3

Browse files
Stefan Haberlandaxboe
authored andcommitted
s390/dasd: fix command reject error on ESE devices
Formatting a thin-provisioned (ESE) device that is part of a PPRC copy relation might fail with the following error: dasd-eckd 0.0.f500: An error occurred in the DASD device driver, reason=09 [...] 24 Byte: 0 MSG 4, no MSGb to SYSOP During format of an ESE disk the Release Allocated Space command is used. A bit in the payload of the command is set that is not allowed to be set for devices in a copy relation. This bit is set to allow the partial release of an extent. Check for the existence of a copy relation before setting the respective bit. Fixes: 91dc4a1 ("s390/dasd: Add new ioctl to release space") Cc: stable@kernel.org # 5.3+ Signed-off-by: Stefan Haberland <sth@linux.ibm.com> Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com> Link: https://lore.kernel.org/r/20230519102340.3854819-2-sth@linux.ibm.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 1878b73 commit c99bff3

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

drivers/s390/block/dasd_eckd.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ static int prepare_itcw(struct itcw *, unsigned int, unsigned int, int,
127127
struct dasd_device *, struct dasd_device *,
128128
unsigned int, int, unsigned int, unsigned int,
129129
unsigned int, unsigned int);
130+
static int dasd_eckd_query_pprc_status(struct dasd_device *,
131+
struct dasd_pprc_data_sc4 *);
130132

131133
/* initial attempt at a probe function. this can be simplified once
132134
* the other detection code is gone */
@@ -3733,6 +3735,26 @@ static int count_exts(unsigned int from, unsigned int to, int trks_per_ext)
37333735
return count;
37343736
}
37353737

3738+
static int dasd_in_copy_relation(struct dasd_device *device)
3739+
{
3740+
struct dasd_pprc_data_sc4 *temp;
3741+
int rc;
3742+
3743+
if (!dasd_eckd_pprc_enabled(device))
3744+
return 0;
3745+
3746+
temp = kzalloc(sizeof(*temp), GFP_KERNEL);
3747+
if (!temp)
3748+
return -ENOMEM;
3749+
3750+
rc = dasd_eckd_query_pprc_status(device, temp);
3751+
if (!rc)
3752+
rc = temp->dev_info[0].state;
3753+
3754+
kfree(temp);
3755+
return rc;
3756+
}
3757+
37363758
/*
37373759
* Release allocated space for a given range or an entire volume.
37383760
*/
@@ -3749,6 +3771,7 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
37493771
int cur_to_trk, cur_from_trk;
37503772
struct dasd_ccw_req *cqr;
37513773
u32 beg_cyl, end_cyl;
3774+
int copy_relation;
37523775
struct ccw1 *ccw;
37533776
int trks_per_ext;
37543777
size_t ras_size;
@@ -3760,6 +3783,10 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
37603783
if (dasd_eckd_ras_sanity_checks(device, first_trk, last_trk))
37613784
return ERR_PTR(-EINVAL);
37623785

3786+
copy_relation = dasd_in_copy_relation(device);
3787+
if (copy_relation < 0)
3788+
return ERR_PTR(copy_relation);
3789+
37633790
rq = req ? blk_mq_rq_to_pdu(req) : NULL;
37643791

37653792
features = &private->features;
@@ -3788,9 +3815,11 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
37883815
/*
37893816
* This bit guarantees initialisation of tracks within an extent that is
37903817
* not fully specified, but is only supported with a certain feature
3791-
* subset.
3818+
* subset and for devices not in a copy relation.
37923819
*/
3793-
ras_data->op_flags.guarantee_init = !!(features->feature[56] & 0x01);
3820+
if (features->feature[56] & 0x01 && !copy_relation)
3821+
ras_data->op_flags.guarantee_init = 1;
3822+
37943823
ras_data->lss = private->conf.ned->ID;
37953824
ras_data->dev_addr = private->conf.ned->unit_addr;
37963825
ras_data->nr_exts = nr_exts;

0 commit comments

Comments
 (0)