aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-05-16 07:13:16 -0400
committerSteve French <sfrench@us.ibm.com>2012-05-16 21:13:29 -0400
commit8d5ce4d23c79e0f9861b19fc534f5b2dc636f79c (patch)
tree5f9583d0b3d63e142ec4bbda6058da906a8273f6 /fs/cifs/cifssmb.c
parent0471ca3fe481cf5ff0ae24c7003f4d9086a02791 (diff)
cifs: abstract out function to marshal the iovec for readv receives
Cached and uncached reads will need to do different things here to handle the difference when the pages are in pagecache and not. Abstract out the function that marshals the page list into a kvec array. Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c67
1 files changed, 4 insertions, 63 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index d263f98aab91..3aa1fcc15156 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1436,13 +1436,10 @@ static int
1436cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) 1436cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1437{ 1437{
1438 int length, len; 1438 int length, len;
1439 unsigned int data_offset, remaining, data_len; 1439 unsigned int data_offset, data_len;
1440 struct cifs_readdata *rdata = mid->callback_data; 1440 struct cifs_readdata *rdata = mid->callback_data;
1441 char *buf = server->smallbuf; 1441 char *buf = server->smallbuf;
1442 unsigned int buflen = get_rfc1002_length(buf) + 4; 1442 unsigned int buflen = get_rfc1002_length(buf) + 4;
1443 u64 eof;
1444 pgoff_t eof_index;
1445 struct page *page, *tpage;
1446 1443
1447 cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__, 1444 cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
1448 mid->mid, rdata->offset, rdata->bytes); 1445 mid->mid, rdata->offset, rdata->bytes);
@@ -1525,64 +1522,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1525 } 1522 }
1526 1523
1527 /* marshal up the page array */ 1524 /* marshal up the page array */
1528 len = 0; 1525 len = rdata->marshal_iov(rdata, data_len);
1529 remaining = data_len; 1526 data_len -= len;
1530 rdata->nr_iov = 1;
1531
1532 /* determine the eof that the server (probably) has */
1533 eof = CIFS_I(rdata->mapping->host)->server_eof;
1534 eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
1535 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
1536
1537 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1538 if (remaining >= PAGE_CACHE_SIZE) {
1539 /* enough data to fill the page */
1540 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1541 rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
1542 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1543 rdata->nr_iov, page->index,
1544 rdata->iov[rdata->nr_iov].iov_base,
1545 rdata->iov[rdata->nr_iov].iov_len);
1546 ++rdata->nr_iov;
1547 len += PAGE_CACHE_SIZE;
1548 remaining -= PAGE_CACHE_SIZE;
1549 } else if (remaining > 0) {
1550 /* enough for partial page, fill and zero the rest */
1551 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1552 rdata->iov[rdata->nr_iov].iov_len = remaining;
1553 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1554 rdata->nr_iov, page->index,
1555 rdata->iov[rdata->nr_iov].iov_base,
1556 rdata->iov[rdata->nr_iov].iov_len);
1557 memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
1558 '\0', PAGE_CACHE_SIZE - remaining);
1559 ++rdata->nr_iov;
1560 len += remaining;
1561 remaining = 0;
1562 } else if (page->index > eof_index) {
1563 /*
1564 * The VFS will not try to do readahead past the
1565 * i_size, but it's possible that we have outstanding
1566 * writes with gaps in the middle and the i_size hasn't
1567 * caught up yet. Populate those with zeroed out pages
1568 * to prevent the VFS from repeatedly attempting to
1569 * fill them until the writes are flushed.
1570 */
1571 zero_user(page, 0, PAGE_CACHE_SIZE);
1572 list_del(&page->lru);
1573 lru_cache_add_file(page);
1574 flush_dcache_page(page);
1575 SetPageUptodate(page);
1576 unlock_page(page);
1577 page_cache_release(page);
1578 } else {
1579 /* no need to hold page hostage */
1580 list_del(&page->lru);
1581 lru_cache_add_file(page);
1582 unlock_page(page);
1583 page_cache_release(page);
1584 }
1585 }
1586 1527
1587 /* issue the read if we have any iovecs left to fill */ 1528 /* issue the read if we have any iovecs left to fill */
1588 if (rdata->nr_iov > 1) { 1529 if (rdata->nr_iov > 1) {
@@ -1598,7 +1539,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1598 rdata->bytes = length; 1539 rdata->bytes = length;
1599 1540
1600 cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read, 1541 cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read,
1601 buflen, remaining); 1542 buflen, data_len);
1602 1543
1603 /* discard anything left over */ 1544 /* discard anything left over */
1604 if (server->total_read < buflen) 1545 if (server->total_read < buflen)