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

Commit b43e93ed authored by Stefan Haberland's avatar Stefan Haberland Committed by Sasha Levin
Browse files

s390/dasd: fix refcount for PAV reassignment



[ Upstream commit 9d862ababb609439c5d6987f6d3ddd09e703aa0b ]

Add refcount to the DASD device when a summary unit check worker is
scheduled. This prevents that the device is set offline with worker
in place.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarStefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
parent ef09ae75
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -264,18 +264,22 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
		spin_unlock_irqrestore(&lcu->lock, flags);
		cancel_work_sync(&lcu->suc_data.worker);
		spin_lock_irqsave(&lcu->lock, flags);
		if (device == lcu->suc_data.device)
		if (device == lcu->suc_data.device) {
			dasd_put_device(device);
			lcu->suc_data.device = NULL;
		}
	}
	was_pending = 0;
	if (device == lcu->ruac_data.device) {
		spin_unlock_irqrestore(&lcu->lock, flags);
		was_pending = 1;
		cancel_delayed_work_sync(&lcu->ruac_data.dwork);
		spin_lock_irqsave(&lcu->lock, flags);
		if (device == lcu->ruac_data.device)
		if (device == lcu->ruac_data.device) {
			dasd_put_device(device);
			lcu->ruac_data.device = NULL;
		}
	}
	private->lcu = NULL;
	spin_unlock_irqrestore(&lcu->lock, flags);

@@ -549,8 +553,10 @@ static void lcu_update_work(struct work_struct *work)
	if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
		DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
			    " alias data in lcu (rc = %d), retry later", rc);
		schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
		if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
			dasd_put_device(device);
	} else {
		dasd_put_device(device);
		lcu->ruac_data.device = NULL;
		lcu->flags &= ~UPDATE_PENDING;
	}
@@ -593,8 +599,10 @@ static int _schedule_lcu_update(struct alias_lcu *lcu,
	 */
	if (!usedev)
		return -EINVAL;
	dasd_get_device(usedev);
	lcu->ruac_data.device = usedev;
	schedule_delayed_work(&lcu->ruac_data.dwork, 0);
	if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
		dasd_put_device(usedev);
	return 0;
}

@@ -926,6 +934,7 @@ static void summary_unit_check_handling_work(struct work_struct *work)
	/* 3. read new alias configuration */
	_schedule_lcu_update(lcu, device);
	lcu->suc_data.device = NULL;
	dasd_put_device(device);
	spin_unlock_irqrestore(&lcu->lock, flags);
}

@@ -985,6 +994,8 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
	}
	lcu->suc_data.reason = reason;
	lcu->suc_data.device = device;
	dasd_get_device(device);
	spin_unlock(&lcu->lock);
	schedule_work(&lcu->suc_data.worker);
	if (!schedule_work(&lcu->suc_data.worker))
		dasd_put_device(device);
};