dm mpath: add locking to multipath_resume and must_push_back
Multiple flags were being tested without locking. Protect against non-atomic bit changes in m->flags by holding m->lock (while testing or setting the queue_if_no_path related flags). Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
Родитель
99f3c90d0d
Коммит
1814f2e3fb
|
@ -507,13 +507,27 @@ static bool __must_push_back(struct multipath *m)
|
|||
|
||||
static bool must_push_back_rq(struct multipath *m)
|
||||
{
|
||||
return (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) ||
|
||||
__must_push_back(m));
|
||||
bool r;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
r = (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags) ||
|
||||
__must_push_back(m));
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool must_push_back_bio(struct multipath *m)
|
||||
{
|
||||
return __must_push_back(m);
|
||||
bool r;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
r = __must_push_back(m);
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1680,12 +1694,14 @@ static void multipath_postsuspend(struct dm_target *ti)
|
|||
static void multipath_resume(struct dm_target *ti)
|
||||
{
|
||||
struct multipath *m = ti->private;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&m->lock, flags);
|
||||
if (test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags))
|
||||
set_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags);
|
||||
else
|
||||
clear_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags);
|
||||
smp_mb__after_atomic();
|
||||
spin_unlock_irqrestore(&m->lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче