aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
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
commit0471ca3fe481cf5ff0ae24c7003f4d9086a02791 (patch)
treed3d5abc60b7a932210f43fe730f54d3f5359cc3e /fs/cifs
parent0e93b4b304ae052ba1bc73f6d34a68556fe93429 (diff)
cifs: make cifs_readdata_alloc take a work_func_t arg
We'll need different completion routines for an uncached read. Allow the caller to set the one he needs at allocation time. Also, move most of these functions to file.c so we can make more of them static. Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs')
-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) {