shmem: minor fixes to splice-read implementation
HWPoison: my reading of folio_test_hwpoison() is that it only tests the
head page of a large folio, whereas splice_folio_into_pipe() will splice
as much of the folio as it can: so for safety we should also check the
has_hwpoisoned flag, set if any of the folio's pages are hwpoisoned.
(Perhaps that ugliness can be improved at the mm end later.)
The call to splice_zeropage_into_pipe() risked overrunning past EOF: ask
it for "part" not "len".
Link: https://lkml.kernel.org/r/32c72c9c-72a8-115f-407d-f0148f368@google.com
Fixes: bd194b1871
("shmem: Implement splice-read")
Signed-off-by: Hugh Dickins <hughd@google.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
253e5df8b8
commit
fa598952fa
1 changed files with 6 additions and 3 deletions
|
@ -2796,7 +2796,8 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos,
|
|||
if (*ppos >= i_size_read(inode))
|
||||
break;
|
||||
|
||||
error = shmem_get_folio(inode, *ppos / PAGE_SIZE, &folio, SGP_READ);
|
||||
error = shmem_get_folio(inode, *ppos / PAGE_SIZE, &folio,
|
||||
SGP_READ);
|
||||
if (error) {
|
||||
if (error == -EINVAL)
|
||||
error = 0;
|
||||
|
@ -2805,7 +2806,9 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos,
|
|||
if (folio) {
|
||||
folio_unlock(folio);
|
||||
|
||||
if (folio_test_hwpoison(folio)) {
|
||||
if (folio_test_hwpoison(folio) ||
|
||||
(folio_test_large(folio) &&
|
||||
folio_test_has_hwpoisoned(folio))) {
|
||||
error = -EIO;
|
||||
break;
|
||||
}
|
||||
|
@ -2841,7 +2844,7 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos,
|
|||
folio_put(folio);
|
||||
folio = NULL;
|
||||
} else {
|
||||
n = splice_zeropage_into_pipe(pipe, *ppos, len);
|
||||
n = splice_zeropage_into_pipe(pipe, *ppos, part);
|
||||
}
|
||||
|
||||
if (!n)
|
||||
|
|
Loading…
Reference in a new issue