Skip to content

Commit

Permalink
CIFS: Fix splice read for non-cached files
Browse files Browse the repository at this point in the history
commit 9c25702 upstream.

Currently we call copy_page_to_iter() for uncached reading into a pipe.
This is wrong because it treats pages as VFS cache pages and copies references
rather than actual data. When we are trying to read from the pipe we end up
calling page_cache_pipe_buf_confirm() which returns -ENODATA. This error
is translated into 0 which is returned to a user.

This issue is reproduced by running xfs-tests suite (generic test torvalds#249)
against mount points with "cache=none". Fix it by mapping pages manually
and calling copy_to_iter() that copies data into the pipe.

Signed-off-by: Pavel Shilovsky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
piastry authored and gregkh committed Mar 12, 2017
1 parent 9d65432 commit 069634b
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2884,7 +2884,15 @@ cifs_readdata_to_iov(struct cifs_readdata *rdata, struct iov_iter *iter)
for (i = 0; i < rdata->nr_pages; i++) {
struct page *page = rdata->pages[i];
size_t copy = min_t(size_t, remaining, PAGE_SIZE);
size_t written = copy_page_to_iter(page, 0, copy, iter);
size_t written;

if (unlikely(iter->type & ITER_PIPE)) {
void *addr = kmap_atomic(page);

written = copy_to_iter(addr, copy, iter);
kunmap_atomic(addr);
} else
written = copy_page_to_iter(page, 0, copy, iter);
remaining -= written;
if (written < copy && iov_iter_count(iter) > 0)
break;
Expand Down

0 comments on commit 069634b

Please sign in to comment.