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

Commit a809f6d8 authored by Khazhismel Kumykov's avatar Khazhismel Kumykov Committed by Greg Kroah-Hartman
Browse files

dm resume: don't return EINVAL when signalled



commit 7a636b4f03af9d541205f69e373672e7b2b60a8a upstream.

If the dm_resume method is called on a device that is not suspended, the
method will suspend the device briefly, before resuming it (so that the
table will be swapped).

However, there was a bug that the return value of dm_suspended_md was not
checked. dm_suspended_md may return an error when it is interrupted by a
signal. In this case, do_resume would call dm_swap_table, which would
return -EINVAL.

This commit fixes the logic, so that error returned by dm_suspend is
checked and the resume operation is undone.

Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Signed-off-by: default avatarKhazhismel Kumykov <khazhy@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2fbc3c67
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -1039,8 +1039,26 @@ static int do_resume(struct dm_ioctl *param)
			suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
		if (param->flags & DM_NOFLUSH_FLAG)
			suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
		if (!dm_suspended_md(md))
			dm_suspend(md, suspend_flags);
		if (!dm_suspended_md(md)) {
			r = dm_suspend(md, suspend_flags);
			if (r) {
				down_write(&_hash_lock);
				hc = dm_get_mdptr(md);
				if (hc && !hc->new_map) {
					hc->new_map = new_map;
					new_map = NULL;
				} else {
					r = -ENXIO;
				}
				up_write(&_hash_lock);
				if (new_map) {
					dm_sync_table(md);
					dm_table_destroy(new_map);
				}
				dm_put(md);
				return r;
			}
		}

		old_map = dm_swap_table(md, new_map);
		if (IS_ERR(old_map)) {