aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c67
-rw-r--r--fs/cifs/file.c68
3 files changed, 74 insertions, 63 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index d57cdf4e2033..f309b43848fb 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -472,6 +472,8 @@ struct cifs_readdata {
472 int result; 472 int result;
473 struct list_head pages; 473 struct list_head pages;
474 struct work_struct work; 474 struct work_struct work;
475 int (*marshal_iov) (struct cifs_readdata *rdata,
476 unsigned int remaining);
475 unsigned int nr_iov; 477 unsigned int nr_iov;
476 struct kvec iov[1]; 478 struct kvec iov[1];
477}; 479};
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)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index d210288e4a47..183381d9c4c1 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2654,6 +2654,73 @@ cifs_readv_complete(struct work_struct *work)
2654 cifs_readdata_free(rdata); 2654 cifs_readdata_free(rdata);
2655} 2655}
2656 2656
2657static int
2658cifs_readpages_marshal_iov(struct cifs_readdata *rdata, unsigned int remaining)
2659{
2660 int len = 0;
2661 struct page *page, *tpage;
2662 u64 eof;
2663 pgoff_t eof_index;
2664
2665 /* determine the eof that the server (probably) has */
2666 eof = CIFS_I(rdata->mapping->host)->server_eof;
2667 eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
2668 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
2669
2670 rdata->nr_iov = 1;
2671 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
2672 if (remaining >= PAGE_CACHE_SIZE) {
2673 /* enough data to fill the page */
2674 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
2675 rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
2676 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
2677 rdata->nr_iov, page->index,
2678 rdata->iov[rdata->nr_iov].iov_base,
2679 rdata->iov[rdata->nr_iov].iov_len);
2680 ++rdata->nr_iov;
2681 len += PAGE_CACHE_SIZE;
2682 remaining -= PAGE_CACHE_SIZE;
2683 } else if (remaining > 0) {
2684 /* enough for partial page, fill and zero the rest */
2685 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
2686 rdata->iov[rdata->nr_iov].iov_len = remaining;
2687 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
2688 rdata->nr_iov, page->index,
2689 rdata->iov[rdata->nr_iov].iov_base,
2690 rdata->iov[rdata->nr_iov].iov_len);
2691 memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
2692 '\0', PAGE_CACHE_SIZE - remaining);
2693 ++rdata->nr_iov;
2694 len += remaining;
2695 remaining = 0;
2696 } else if (page->index > eof_index) {
2697 /*
2698 * The VFS will not try to do readahead past the
2699 * i_size, but it's possible that we have outstanding
2700 * writes with gaps in the middle and the i_size hasn't
2701 * caught up yet. Populate those with zeroed out pages
2702 * to prevent the VFS from repeatedly attempting to
2703 * fill them until the writes are flushed.
2704 */
2705 zero_user(page, 0, PAGE_CACHE_SIZE);
2706 list_del(&page->lru);
2707 lru_cache_add_file(page);
2708 flush_dcache_page(page);
2709 SetPageUptodate(page);
2710 unlock_page(page);
2711 page_cache_release(page);
2712 } else {
2713 /* no need to hold page hostage */
2714 list_del(&page->lru);
2715 lru_cache_add_file(page);
2716 unlock_page(page);
2717 page_cache_release(page);
2718 }
2719 }
2720
2721 return len;
2722}
2723
2657static int cifs_readpages(struct file *file, struct address_space *mapping, 2724static int cifs_readpages(struct file *file, struct address_space *mapping,
2658 struct list_head *page_list, unsigned num_pages) 2725 struct list_head *page_list, unsigned num_pages)
2659{ 2726{
@@ -2777,6 +2844,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2777 rdata->offset = offset; 2844 rdata->offset = offset;
2778 rdata->bytes = bytes; 2845 rdata->bytes = bytes;
2779 rdata->pid = pid; 2846 rdata->pid = pid;
2847 rdata->marshal_iov = cifs_readpages_marshal_iov;
2780 list_splice_init(&tmplist, &rdata->pages); 2848 list_splice_init(&tmplist, &rdata->pages);
2781 2849
2782 do { 2850 do {