Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46d1c03c authored by Jan Höppner's avatar Jan Höppner Committed by Martin Schwidefsky
Browse files

s390/dasd: Improve dasd format code



- Make sure a calling function can rely on data in fdata by resetting to
  its initial values
- Move special treatment for track 0 and 1 to dasd_eckd_build_format
- Replace dangerous backward goto with a loop logic
- Add define for number that specifies the maximum amount of CCWs per
  request and is used for format_step calculation
- Remove unused variable

Signed-off-by: default avatarJan Höppner <hoeppner@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent f369b98e
Loading
Loading
Loading
Loading
+52 −58
Original line number Diff line number Diff line
@@ -2349,14 +2349,14 @@ dasd_eckd_build_format(struct dasd_device *base,
				 * when formatting CDL
				 */
				if ((intensity & 0x08) &&
				    fdata->start_unit == 0) {
				    address.cyl == 0 && address.head == 0) {
					if (i < 3) {
						ect->kl = 4;
						ect->dl = sizes_trk0[i] - 4;
					}
				}
				if ((intensity & 0x08) &&
				    fdata->start_unit == 1) {
				    address.cyl == 0 && address.head == 1) {
					ect->kl = 44;
					ect->dl = LABEL_SIZE - 44;
				}
@@ -2392,14 +2392,13 @@ dasd_eckd_format_device(struct dasd_device *base,
			int enable_pav)
{
	struct dasd_ccw_req *cqr, *n;
	struct dasd_block *block;
	struct dasd_eckd_private *private;
	struct list_head format_queue;
	struct dasd_device *device;
	int old_stop, format_step;
	int step, rc = 0, sleep_rc;
	int old_start, old_stop, format_step;
	int step, retry;
	int rc = 0;

	block = base->block;
	private = (struct dasd_eckd_private *) base->private;

	/* Sanity checks. */
@@ -2432,49 +2431,45 @@ dasd_eckd_format_device(struct dasd_device *base,

	INIT_LIST_HEAD(&format_queue);

	old_start = fdata->start_unit;
	old_stop = fdata->stop_unit;
	while (fdata->start_unit <= 1) {
		fdata->stop_unit = fdata->start_unit;
		cqr = dasd_eckd_build_format(base, fdata, enable_pav);
		list_add(&cqr->blocklist, &format_queue);

		fdata->stop_unit = old_stop;
		fdata->start_unit++;

		if (fdata->start_unit > fdata->stop_unit)
			goto sleep;
	}

retry:
	format_step = 255 / recs_per_track(&private->rdc_data, 0,
	format_step = DASD_CQR_MAX_CCW / recs_per_track(&private->rdc_data, 0,
							fdata->blksize);
	do {
		retry = 0;
		while (fdata->start_unit <= old_stop) {
			step = fdata->stop_unit - fdata->start_unit + 1;
		if (step > format_step)
			fdata->stop_unit = fdata->start_unit + format_step - 1;
			if (step > format_step) {
				fdata->stop_unit =
					fdata->start_unit + format_step - 1;
			}

			cqr = dasd_eckd_build_format(base, fdata, enable_pav);
			if (IS_ERR(cqr)) {
			if (PTR_ERR(cqr) == -ENOMEM) {
				rc = PTR_ERR(cqr);
				if (rc == -ENOMEM) {
					if (list_empty(&format_queue))
						goto out;
					/*
				 * not enough memory available
				 * go to out and start requests
				 * retry after first requests were finished
					 * not enough memory available, start
					 * requests retry after first requests
					 * were finished
					 */
				fdata->stop_unit = old_stop;
				goto sleep;
			} else
				return PTR_ERR(cqr);
					retry = 1;
					break;
				}
				goto out_err;
			}
		list_add(&cqr->blocklist, &format_queue);
			list_add_tail(&cqr->blocklist, &format_queue);

			fdata->start_unit = fdata->stop_unit + 1;
			fdata->stop_unit = old_stop;
		}

sleep:
	sleep_rc = dasd_sleep_on_queue(&format_queue);
		rc = dasd_sleep_on_queue(&format_queue);

out_err:
		list_for_each_entry_safe(cqr, n, &format_queue, blocklist) {
			device = cqr->startdev;
			private = (struct dasd_eckd_private *) device->private;
@@ -2485,15 +2480,14 @@ dasd_eckd_format_device(struct dasd_device *base,
			private->count--;
		}

	if (sleep_rc)
		return sleep_rc;
		if (rc)
			goto out;

	} while (retry);

	/*
	 * in case of ENOMEM we need to retry after
	 * first requests are finished
	 */
	if (fdata->start_unit <= fdata->stop_unit)
		goto retry;
out:
	fdata->start_unit = old_start;
	fdata->stop_unit = old_stop;

	return rc;
}
+7 −0
Original line number Diff line number Diff line
@@ -240,6 +240,13 @@ struct dasd_ccw_req {
/* Signature for error recovery functions. */
typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);

/*
 * A single CQR can only contain a maximum of 255 CCWs. It is limited by
 * the locate record and locate record extended count value which can only hold
 * 1 Byte max.
 */
#define DASD_CQR_MAX_CCW 255

/*
 * Unique identifier for dasd device.
 */