Unverified Commit caaf346b authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!12045 s390/dasd: fix error recovery leading to data corruption on ESE devices

parents 4bfa88f2 5e019176
Loading
Loading
Loading
Loading
+23 −13
Original line number Diff line number Diff line
@@ -1665,9 +1665,15 @@ static int dasd_ese_needs_format(struct dasd_block *block, struct irb *irb)
	if (!sense)
		return 0;

	return !!(sense[1] & SNS1_NO_REC_FOUND) ||
		!!(sense[1] & SNS1_FILE_PROTECTED) ||
		scsw_cstat(&irb->scsw) == SCHN_STAT_INCORR_LEN;
	if (sense[1] & SNS1_NO_REC_FOUND)
		return 1;

	if ((sense[1] & SNS1_INV_TRACK_FORMAT) &&
	    scsw_is_tm(&irb->scsw) &&
	    !(sense[2] & SNS2_ENV_DATA_PRESENT))
		return 1;

	return 0;
}

static int dasd_ese_oos_cond(u8 *sense)
@@ -1688,7 +1694,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
	struct dasd_device *device;
	unsigned long now;
	int nrf_suppressed = 0;
	int fp_suppressed = 0;
	int it_suppressed = 0;
	struct request *req;
	u8 *sense = NULL;
	int expires;
@@ -1743,8 +1749,9 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
		 */
		sense = dasd_get_sense(irb);
		if (sense) {
			fp_suppressed = (sense[1] & SNS1_FILE_PROTECTED) &&
				test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
			it_suppressed =	(sense[1] & SNS1_INV_TRACK_FORMAT) &&
				!(sense[2] & SNS2_ENV_DATA_PRESENT) &&
				test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
			nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) &&
				test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);

@@ -1759,7 +1766,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
				return;
			}
		}
		if (!(fp_suppressed || nrf_suppressed))
		if (!(it_suppressed || nrf_suppressed))
			device->discipline->dump_sense_dbf(device, irb, "int");

		if (device->features & DASD_FEATURE_ERPLOG)
@@ -2513,14 +2520,17 @@ static int _dasd_sleep_on_queue(struct list_head *ccw_queue, int interruptible)
	rc = 0;
	list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) {
		/*
		 * In some cases the 'File Protected' or 'Incorrect Length'
		 * error might be expected and error recovery would be
		 * unnecessary in these cases.	Check if the according suppress
		 * bit is set.
		 * In some cases certain errors might be expected and
		 * error recovery would be unnecessary in these cases.
		 * Check if the according suppress bit is set.
		 */
		sense = dasd_get_sense(&cqr->irb);
		if (sense && sense[1] & SNS1_FILE_PROTECTED &&
		    test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags))
		if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) &&
		    !(sense[2] & SNS2_ENV_DATA_PRESENT) &&
		    test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags))
			continue;
		if (sense && (sense[1] & SNS1_NO_REC_FOUND) &&
		    test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags))
			continue;
		if (scsw_cstat(&cqr->irb.scsw) == 0x40 &&
		    test_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags))
+2 −8
Original line number Diff line number Diff line
@@ -1401,12 +1401,6 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)

	struct dasd_device *device = erp->startdev;

	/*
	 * In some cases the 'File Protected' error might be expected and
	 * log messages shouldn't be written then.
	 * Check if the according suppress bit is set.
	 */
	if (!test_bit(DASD_CQR_SUPPRESS_FP, &erp->flags))
	dev_err(&device->cdev->dev,
		"Accessing the DASD failed because of a hardware error\n");

+24 −31
Original line number Diff line number Diff line
@@ -2201,6 +2201,7 @@ dasd_eckd_analysis_ccw(struct dasd_device *device)
	cqr->status = DASD_CQR_FILLED;
	/* Set flags to suppress output for expected errors */
	set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
	set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);

	return cqr;
}
@@ -2482,7 +2483,6 @@ dasd_eckd_build_check_tcw(struct dasd_device *base, struct format_data_t *fdata,
	cqr->buildclk = get_tod_clock();
	cqr->status = DASD_CQR_FILLED;
	/* Set flags to suppress output for expected errors */
	set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
	set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);

	return cqr;
@@ -4031,8 +4031,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(

	/* Set flags to suppress output for expected errors */
	if (dasd_eckd_is_ese(basedev)) {
		set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
		set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
		set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
	}

@@ -4534,9 +4532,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(

	/* Set flags to suppress output for expected errors */
	if (dasd_eckd_is_ese(basedev)) {
		set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
		set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
		set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
		set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
	}

	return cqr;
@@ -5706,26 +5703,16 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
{
	u8 *sense = dasd_get_sense(irb);

	if (scsw_is_tm(&irb->scsw)) {
	/*
		 * In some cases the 'File Protected' or 'Incorrect Length'
		 * error might be expected and log messages shouldn't be written
		 * then. Check if the according suppress bit is set.
	 * In some cases certain errors might be expected and
	 * log messages shouldn't be written then.
	 * Check if the according suppress bit is set.
	 */
		if (sense && (sense[1] & SNS1_FILE_PROTECTED) &&
		    test_bit(DASD_CQR_SUPPRESS_FP, &req->flags))
			return;
		if (scsw_cstat(&irb->scsw) == 0x40 &&
		    test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))
	if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) &&
	    !(sense[2] & SNS2_ENV_DATA_PRESENT) &&
	    test_bit(DASD_CQR_SUPPRESS_IT, &req->flags))
		return;

		dasd_eckd_dump_sense_tcw(device, req, irb);
	} else {
		/*
		 * In some cases the 'Command Reject' or 'No Record Found'
		 * error might be expected and log messages shouldn't be
		 * written then. Check if the according suppress bit is set.
		 */
	if (sense && sense[0] & SNS0_CMD_REJECT &&
	    test_bit(DASD_CQR_SUPPRESS_CR, &req->flags))
		return;
@@ -5734,9 +5721,15 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
	    test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags))
		return;

	if (scsw_cstat(&irb->scsw) == 0x40 &&
	    test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))
		return;

	if (scsw_is_tm(&irb->scsw))
		dasd_eckd_dump_sense_tcw(device, req, irb);
	else
		dasd_eckd_dump_sense_ccw(device, req, irb);
}
}

static int dasd_eckd_pm_freeze(struct dasd_device *device)
{
+1 −1
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ struct dasd_ccw_req {
 * The following flags are used to suppress output of certain errors.
 */
#define DASD_CQR_SUPPRESS_NRF	4	/* Suppress 'No Record Found' error */
#define DASD_CQR_SUPPRESS_FP	5	/* Suppress 'File Protected' error*/
#define DASD_CQR_SUPPRESS_IT	5	/* Suppress 'Invalid Track' error*/
#define DASD_CQR_SUPPRESS_IL	6	/* Suppress 'Incorrect Length' error */
#define DASD_CQR_SUPPRESS_CR	7	/* Suppress 'Command Reject' error */