do_generic_file_read: s/EINTR/EIO/ if lock_page_killable() fails
If lock_page_killable() fails because the task was killed by SIGKILL or any other fatal signal, do_generic_file_read() returns -EIO. This seems to be OK, because in fact the userspace won't see this error, the task will dequeue SIGKILL and exit. However, /sbin/init is different, it will dequeue SIGKILL, ignore it, and return to the user-space with the bogus -EIO. Change the code to return the error code from lock_page_killable(), -EINTR. This doesn't fix the bug, but perhaps makes sense anyway. Imho, with this change the code looks a bit more logical, and the "good" init should handle the spurious EINTR or short read. Afaics we can also change lock_page_killable() to return -ERESTARTNOINTR, but this can't prevent the short reads. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Родитель
7591103c08
Коммит
8546232355
15
mm/filemap.c
15
mm/filemap.c
|
@ -1100,8 +1100,9 @@ page_ok:
|
||||||
|
|
||||||
page_not_up_to_date:
|
page_not_up_to_date:
|
||||||
/* Get exclusive access to the page ... */
|
/* Get exclusive access to the page ... */
|
||||||
if (lock_page_killable(page))
|
error = lock_page_killable(page);
|
||||||
goto readpage_eio;
|
if (unlikely(error))
|
||||||
|
goto readpage_error;
|
||||||
|
|
||||||
page_not_up_to_date_locked:
|
page_not_up_to_date_locked:
|
||||||
/* Did it get truncated before we got the lock? */
|
/* Did it get truncated before we got the lock? */
|
||||||
|
@ -1130,8 +1131,9 @@ readpage:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PageUptodate(page)) {
|
if (!PageUptodate(page)) {
|
||||||
if (lock_page_killable(page))
|
error = lock_page_killable(page);
|
||||||
goto readpage_eio;
|
if (unlikely(error))
|
||||||
|
goto readpage_error;
|
||||||
if (!PageUptodate(page)) {
|
if (!PageUptodate(page)) {
|
||||||
if (page->mapping == NULL) {
|
if (page->mapping == NULL) {
|
||||||
/*
|
/*
|
||||||
|
@ -1143,15 +1145,14 @@ readpage:
|
||||||
}
|
}
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
shrink_readahead_size_eio(filp, ra);
|
shrink_readahead_size_eio(filp, ra);
|
||||||
goto readpage_eio;
|
error = -EIO;
|
||||||
|
goto readpage_error;
|
||||||
}
|
}
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
goto page_ok;
|
goto page_ok;
|
||||||
|
|
||||||
readpage_eio:
|
|
||||||
error = -EIO;
|
|
||||||
readpage_error:
|
readpage_error:
|
||||||
/* UHHUH! A synchronous read error occurred. Report it */
|
/* UHHUH! A synchronous read error occurred. Report it */
|
||||||
desc->error = error;
|
desc->error = error;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче