diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-01-09 19:54:50 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-28 14:05:52 -0400 |
commit | 71335664c38f03de10d7cf1d82705fe55a130b33 (patch) | |
tree | 3a098dc6f5355f77fa4f55e987ae1d8aaeb9ed29 /fs/cifs/file.c | |
parent | a6137305a8c47fa92ab1a8efcfe76f0e9fa96ab7 (diff) |
cifs: don't bother with kmap on read_pages side
just do ITER_BVEC recvmsg
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 53 |
1 files changed, 17 insertions, 36 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ff882aeaccc6..0f718679186e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2855,39 +2855,31 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server, int result = 0; unsigned int i; unsigned int nr_pages = rdata->nr_pages; - struct kvec iov; rdata->got_bytes = 0; rdata->tailsz = PAGE_SIZE; for (i = 0; i < nr_pages; i++) { struct page *page = rdata->pages[i]; + size_t n; - if (len >= PAGE_SIZE) { - /* enough data to fill the page */ - iov.iov_base = kmap(page); - iov.iov_len = PAGE_SIZE; - cifs_dbg(FYI, "%u: iov_base=%p iov_len=%zu\n", - i, iov.iov_base, iov.iov_len); - len -= PAGE_SIZE; - } else if (len > 0) { - /* enough for partial page, fill and zero the rest */ - iov.iov_base = kmap(page); - iov.iov_len = len; - cifs_dbg(FYI, "%u: iov_base=%p iov_len=%zu\n", - i, iov.iov_base, iov.iov_len); - memset(iov.iov_base + len, '\0', PAGE_SIZE - len); - rdata->tailsz = len; - len = 0; - } else { + if (len <= 0) { /* no need to hold page hostage */ rdata->pages[i] = NULL; rdata->nr_pages--; put_page(page); continue; } - - result = cifs_readv_from_socket(server, &iov, 1, iov.iov_len); - kunmap(page); + n = len; + if (len >= PAGE_SIZE) { + /* enough data to fill the page */ + n = PAGE_SIZE; + len -= n; + } else { + zero_user(page, len, PAGE_SIZE - len); + rdata->tailsz = len; + len = 0; + } + result = cifs_read_page_from_socket(server, page, n); if (result < 0) break; @@ -3303,7 +3295,6 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, u64 eof; pgoff_t eof_index; unsigned int nr_pages = rdata->nr_pages; - struct kvec iov; /* determine the eof that the server (probably) has */ eof = CIFS_I(rdata->mapping->host)->server_eof; @@ -3314,23 +3305,14 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, rdata->tailsz = PAGE_CACHE_SIZE; for (i = 0; i < nr_pages; i++) { struct page *page = rdata->pages[i]; + size_t n = PAGE_CACHE_SIZE; if (len >= PAGE_CACHE_SIZE) { - /* enough data to fill the page */ - iov.iov_base = kmap(page); - iov.iov_len = PAGE_CACHE_SIZE; - cifs_dbg(FYI, "%u: idx=%lu iov_base=%p iov_len=%zu\n", - i, page->index, iov.iov_base, iov.iov_len); len -= PAGE_CACHE_SIZE; } else if (len > 0) { /* enough for partial page, fill and zero the rest */ - iov.iov_base = kmap(page); - iov.iov_len = len; - cifs_dbg(FYI, "%u: idx=%lu iov_base=%p iov_len=%zu\n", - i, page->index, iov.iov_base, iov.iov_len); - memset(iov.iov_base + len, - '\0', PAGE_CACHE_SIZE - len); - rdata->tailsz = len; + zero_user(page, len, PAGE_CACHE_SIZE - len); + n = rdata->tailsz = len; len = 0; } else if (page->index > eof_index) { /* @@ -3360,8 +3342,7 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, continue; } - result = cifs_readv_from_socket(server, &iov, 1, iov.iov_len); - kunmap(page); + result = cifs_read_page_from_socket(server, page, n); if (result < 0) break; |