autofs4: autofs4_wait() vs. autofs4_catatonic_mode() race
We need to recheck ->catatonic after autofs4_wait() got ->wq_mutex for good, or we might end up with wq inserted into queue after autofs4_catatonic_mode() had done its thing. It will stick there forever, since there won't be anything to clear its ->name.name. A bit of a complication: validate_request() drops and regains ->wq_mutex. It actually ends up the most convenient place to stick the check into... Acked-by: Ian Kent <raven@themaw.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
b3f2a92447
Коммит
4041bcdc7b
|
@ -257,6 +257,9 @@ static int validate_request(struct autofs_wait_queue **wait,
|
|||
struct autofs_wait_queue *wq;
|
||||
struct autofs_info *ino;
|
||||
|
||||
if (sbi->catatonic)
|
||||
return -ENOENT;
|
||||
|
||||
/* Wait in progress, continue; */
|
||||
wq = autofs4_find_wait(sbi, qstr);
|
||||
if (wq) {
|
||||
|
@ -289,6 +292,9 @@ static int validate_request(struct autofs_wait_queue **wait,
|
|||
if (mutex_lock_interruptible(&sbi->wq_mutex))
|
||||
return -EINTR;
|
||||
|
||||
if (sbi->catatonic)
|
||||
return -ENOENT;
|
||||
|
||||
wq = autofs4_find_wait(sbi, qstr);
|
||||
if (wq) {
|
||||
*wait = wq;
|
||||
|
@ -389,7 +395,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
|
|||
|
||||
ret = validate_request(&wq, sbi, &qstr, dentry, notify);
|
||||
if (ret <= 0) {
|
||||
if (ret == 0)
|
||||
if (ret != -EINTR)
|
||||
mutex_unlock(&sbi->wq_mutex);
|
||||
kfree(qstr.name);
|
||||
return ret;
|
||||
|
|
Загрузка…
Ссылка в новой задаче