mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-26 12:34:41 +08:00
dm resume: don't return EINVAL when signalled
commit 7a636b4f03
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:
parent
fbea98895f
commit
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);
|
||||
|
Loading…
Reference in New Issue
Block a user