[<prev] [next>] [day] [month] [year] [list]
Message-ID: <ffe97384-f862-afe0-b83-bcfd2b65b72@redhat.com>
Date: Mon, 5 Aug 2024 17:40:53 +0200 (CEST)
From: Mikulas Patocka <mpatocka@...hat.com>
To: Alasdair Kergon <agk@...hat.com>, Mike Snitzer <snitzer@...nel.org>,
dm-devel@...ts.linux.dev, linux-kernel@...r.kernel.org,
Khazhismel Kumykov <khazhy@...gle.com>,
Zdenek Kabelac <zdenek.kabelac@...il.com>
Subject: [PATCH 2/2] dm resume: don't return EINVAL when signalled
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 reusme operation is undone.
Signed-off-by: Mikulas Patocka <mpatocka@...hat.com>
Signed-off-by: Khazhismel Kumykov <khazhy@...gle.com>
---
drivers/md/dm-ioctl.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
Index: linux-2.6/drivers/md/dm-ioctl.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-ioctl.c 2024-05-15 16:55:57.000000000 +0200
+++ linux-2.6/drivers/md/dm-ioctl.c 2024-08-05 17:35:32.000000000 +0200
@@ -1181,8 +1181,24 @@ static int do_resume(struct dm_ioctl *pa
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_table_destroy(new_map);
+ dm_put(md);
+ return r;
+ }
+ }
old_size = dm_get_size(md);
old_map = dm_swap_table(md, new_map);
Powered by blists - more mailing lists