Skip to content

Commit eaf9a73

Browse files
committed
dm: set DMF_SUSPENDED* _before_ clearing DMF_NOFLUSH_SUSPENDING
Otherwise, there is potential for both DMF_SUSPENDED* and DMF_NOFLUSH_SUSPENDING to not be set during dm_suspend() -- which is definitely _not_ a valid state. This fix, in conjuction with "dm rq: fix the starting and stopping of blk-mq queues", addresses the potential for request-based DM multipath's __multipath_map() to see !dm_noflush_suspending() during suspend. Reported-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org
1 parent 7d9595d commit eaf9a73

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

drivers/md/dm.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2082,7 +2082,8 @@ static void unlock_fs(struct mapped_device *md)
20822082
* Caller must hold md->suspend_lock
20832083
*/
20842084
static int __dm_suspend(struct mapped_device *md, struct dm_table *map,
2085-
unsigned suspend_flags, int interruptible)
2085+
unsigned suspend_flags, int interruptible,
2086+
int dmf_suspended_flag)
20862087
{
20872088
bool do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG;
20882089
bool noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG;
@@ -2149,6 +2150,8 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map,
21492150
* to finish.
21502151
*/
21512152
r = dm_wait_for_completion(md, interruptible);
2153+
if (!r)
2154+
set_bit(dmf_suspended_flag, &md->flags);
21522155

21532156
if (noflush)
21542157
clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
@@ -2210,12 +2213,10 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
22102213

22112214
map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
22122215

2213-
r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE);
2216+
r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE, DMF_SUSPENDED);
22142217
if (r)
22152218
goto out_unlock;
22162219

2217-
set_bit(DMF_SUSPENDED, &md->flags);
2218-
22192220
dm_table_postsuspend_targets(map);
22202221

22212222
out_unlock:
@@ -2309,9 +2310,8 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla
23092310
* would require changing .presuspend to return an error -- avoid this
23102311
* until there is a need for more elaborate variants of internal suspend.
23112312
*/
2312-
(void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE);
2313-
2314-
set_bit(DMF_SUSPENDED_INTERNALLY, &md->flags);
2313+
(void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE,
2314+
DMF_SUSPENDED_INTERNALLY);
23152315

23162316
dm_table_postsuspend_targets(map);
23172317
}

0 commit comments

Comments
 (0)