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: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Khazhismel Kumykov <khazhy@google.com> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
fbea98895f
Коммит
5541aec7ff
|
@ -1151,8 +1151,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_size = dm_get_size(md);
|
||||
old_map = dm_swap_table(md, new_map);
|
||||
|
|
Загрузка…
Ссылка в новой задаче