Unverified Commit b8e86304 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files
parents 96697ce8 4cda8de0
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -2707,6 +2707,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla

static void __dm_internal_resume(struct mapped_device *md)
{
	int r;
	struct dm_table *map;

	BUG_ON(!md->internal_suspend_count);

	if (--md->internal_suspend_count)
@@ -2715,12 +2718,23 @@ static void __dm_internal_resume(struct mapped_device *md)
	if (dm_suspended_md(md))
		goto done; /* resume from nested suspend */

	map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
	r = __dm_resume(md, map);
	if (r) {
		/*
	 * NOTE: existing callers don't need to call dm_table_resume_targets
	 * (which may fail -- so best to avoid it for now by passing NULL map)
		 * If a preresume method of some target failed, we are in a
		 * tricky situation. We can't return an error to the caller. We
		 * can't fake success because then the "resume" and
		 * "postsuspend" methods would not be paired correctly, and it
		 * would break various targets, for example it would cause list
		 * corruption in the "origin" target.
		 *
		 * So, we fake normal suspend here, to make sure that the
		 * "resume" and "postsuspend" methods will be paired correctly.
		 */
	(void) __dm_resume(md, NULL);

		DMERR("Preresume method failed: %d", r);
		set_bit(DMF_SUSPENDED, &md->flags);
	}
done:
	clear_bit(DMF_SUSPENDED_INTERNALLY, &md->flags);
	smp_mb__after_atomic();