aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c50
-rw-r--r--fs/cifs/file.c50
3 files changed, 49 insertions, 53 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 96192c1e380a..d57cdf4e2033 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -476,8 +476,6 @@ struct cifs_readdata {
476 struct kvec iov[1]; 476 struct kvec iov[1];
477}; 477};
478 478
479struct cifs_readdata *cifs_readdata_alloc(unsigned int nr_pages);
480void cifs_readdata_free(struct cifs_readdata *rdata);
481int cifs_async_readv(struct cifs_readdata *rdata); 479int cifs_async_readv(struct cifs_readdata *rdata);
482 480
483/* asynchronous write support */ 481/* asynchronous write support */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index da2f5446fa7a..d263f98aab91 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -87,7 +87,6 @@ static struct {
87#endif /* CIFS_POSIX */ 87#endif /* CIFS_POSIX */
88 88
89/* Forward declarations */ 89/* Forward declarations */
90static void cifs_readv_complete(struct work_struct *work);
91 90
92/* Mark as invalid, all open files on tree connections since they 91/* Mark as invalid, all open files on tree connections since they
93 were closed when session to server was lost */ 92 were closed when session to server was lost */
@@ -1385,28 +1384,6 @@ openRetry:
1385 return rc; 1384 return rc;
1386} 1385}
1387 1386
1388struct cifs_readdata *
1389cifs_readdata_alloc(unsigned int nr_pages)
1390{
1391 struct cifs_readdata *rdata;
1392
1393 /* readdata + 1 kvec for each page */
1394 rdata = kzalloc(sizeof(*rdata) +
1395 sizeof(struct kvec) * nr_pages, GFP_KERNEL);
1396 if (rdata != NULL) {
1397 INIT_WORK(&rdata->work, cifs_readv_complete);
1398 INIT_LIST_HEAD(&rdata->pages);
1399 }
1400 return rdata;
1401}
1402
1403void
1404cifs_readdata_free(struct cifs_readdata *rdata)
1405{
1406 cifsFileInfo_put(rdata->cfile);
1407 kfree(rdata);
1408}
1409
1410/* 1387/*
1411 * Discard any remaining data in the current SMB. To do this, we borrow the 1388 * Discard any remaining data in the current SMB. To do this, we borrow the
1412 * current bigbuf. 1389 * current bigbuf.
@@ -1632,33 +1609,6 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1632} 1609}
1633 1610
1634static void 1611static void
1635cifs_readv_complete(struct work_struct *work)
1636{
1637 struct cifs_readdata *rdata = container_of(work,
1638 struct cifs_readdata, work);
1639 struct page *page, *tpage;
1640
1641 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1642 list_del(&page->lru);
1643 lru_cache_add_file(page);
1644
1645 if (rdata->result == 0) {
1646 kunmap(page);
1647 flush_dcache_page(page);
1648 SetPageUptodate(page);
1649 }
1650
1651 unlock_page(page);
1652
1653 if (rdata->result == 0)
1654 cifs_readpage_to_fscache(rdata->mapping->host, page);
1655
1656 page_cache_release(page);
1657 }
1658 cifs_readdata_free(rdata);
1659}
1660
1661static void
1662cifs_readv_callback(struct mid_q_entry *mid) 1612cifs_readv_callback(struct mid_q_entry *mid)
1663{ 1613{
1664 struct cifs_readdata *rdata = mid->callback_data; 1614 struct cifs_readdata *rdata = mid->callback_data;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 81725e9286e9..d210288e4a47 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2339,6 +2339,27 @@ ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
2339 return cifs_user_writev(iocb, iov, nr_segs, pos); 2339 return cifs_user_writev(iocb, iov, nr_segs, pos);
2340} 2340}
2341 2341
2342static struct cifs_readdata *
2343cifs_readdata_alloc(unsigned int nr_vecs, work_func_t complete)
2344{
2345 struct cifs_readdata *rdata;
2346
2347 rdata = kzalloc(sizeof(*rdata) +
2348 sizeof(struct kvec) * nr_vecs, GFP_KERNEL);
2349 if (rdata != NULL) {
2350 INIT_WORK(&rdata->work, complete);
2351 INIT_LIST_HEAD(&rdata->pages);
2352 }
2353 return rdata;
2354}
2355
2356static void
2357cifs_readdata_free(struct cifs_readdata *rdata)
2358{
2359 cifsFileInfo_put(rdata->cfile);
2360 kfree(rdata);
2361}
2362
2342static ssize_t 2363static ssize_t
2343cifs_iovec_read(struct file *file, const struct iovec *iov, 2364cifs_iovec_read(struct file *file, const struct iovec *iov,
2344 unsigned long nr_segs, loff_t *poffset) 2365 unsigned long nr_segs, loff_t *poffset)
@@ -2606,6 +2627,33 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
2606 return rc; 2627 return rc;
2607} 2628}
2608 2629
2630static void
2631cifs_readv_complete(struct work_struct *work)
2632{
2633 struct cifs_readdata *rdata = container_of(work,
2634 struct cifs_readdata, work);
2635 struct page *page, *tpage;
2636
2637 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
2638 list_del(&page->lru);
2639 lru_cache_add_file(page);
2640
2641 if (rdata->result == 0) {
2642 kunmap(page);
2643 flush_dcache_page(page);
2644 SetPageUptodate(page);
2645 }
2646
2647 unlock_page(page);
2648
2649 if (rdata->result == 0)
2650 cifs_readpage_to_fscache(rdata->mapping->host, page);
2651
2652 page_cache_release(page);
2653 }
2654 cifs_readdata_free(rdata);
2655}
2656
2609static int cifs_readpages(struct file *file, struct address_space *mapping, 2657static int cifs_readpages(struct file *file, struct address_space *mapping,
2610 struct list_head *page_list, unsigned num_pages) 2658 struct list_head *page_list, unsigned num_pages)
2611{ 2659{
@@ -2708,7 +2756,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2708 nr_pages++; 2756 nr_pages++;
2709 } 2757 }
2710 2758
2711 rdata = cifs_readdata_alloc(nr_pages); 2759 rdata = cifs_readdata_alloc(nr_pages, cifs_readv_complete);
2712 if (!rdata) { 2760 if (!rdata) {
2713 /* best to give up if we're out of mem */ 2761 /* best to give up if we're out of mem */
2714 list_for_each_entry_safe(page, tpage, &tmplist, lru) { 2762 list_for_each_entry_safe(page, tpage, &tmplist, lru) {