aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/trans_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p/trans_common.c')
-rw-r--r--net/9p/trans_common.c53
1 files changed, 15 insertions, 38 deletions
diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c
index 9a70ebdec56e..de8df957867d 100644
--- a/net/9p/trans_common.c
+++ b/net/9p/trans_common.c
@@ -21,30 +21,25 @@
21 21
22/** 22/**
23 * p9_release_req_pages - Release pages after the transaction. 23 * p9_release_req_pages - Release pages after the transaction.
24 * @*private: PDU's private page of struct trans_rpage_info
25 */ 24 */
26void 25void p9_release_pages(struct page **pages, int nr_pages)
27p9_release_req_pages(struct trans_rpage_info *rpinfo)
28{ 26{
29 int i = 0; 27 int i = 0;
30 28 while (pages[i] && nr_pages--) {
31 while (rpinfo->rp_data[i] && rpinfo->rp_nr_pages--) { 29 put_page(pages[i]);
32 put_page(rpinfo->rp_data[i]);
33 i++; 30 i++;
34 } 31 }
35} 32}
36EXPORT_SYMBOL(p9_release_req_pages); 33EXPORT_SYMBOL(p9_release_pages);
37 34
38/** 35/**
39 * p9_nr_pages - Return number of pages needed to accommodate the payload. 36 * p9_nr_pages - Return number of pages needed to accommodate the payload.
40 */ 37 */
41int 38int p9_nr_pages(char *data, int len)
42p9_nr_pages(struct p9_req_t *req)
43{ 39{
44 unsigned long start_page, end_page; 40 unsigned long start_page, end_page;
45 start_page = (unsigned long)req->tc->pubuf >> PAGE_SHIFT; 41 start_page = (unsigned long)data >> PAGE_SHIFT;
46 end_page = ((unsigned long)req->tc->pubuf + req->tc->pbuf_size + 42 end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
47 PAGE_SIZE - 1) >> PAGE_SHIFT;
48 return end_page - start_page; 43 return end_page - start_page;
49} 44}
50EXPORT_SYMBOL(p9_nr_pages); 45EXPORT_SYMBOL(p9_nr_pages);
@@ -58,35 +53,17 @@ EXPORT_SYMBOL(p9_nr_pages);
58 * @nr_pages: number of pages to accommodate the payload 53 * @nr_pages: number of pages to accommodate the payload
59 * @rw: Indicates if the pages are for read or write. 54 * @rw: Indicates if the pages are for read or write.
60 */ 55 */
61int
62p9_payload_gup(struct p9_req_t *req, size_t *pdata_off, int *pdata_len,
63 int nr_pages, u8 rw)
64{
65 uint32_t first_page_bytes = 0;
66 int32_t pdata_mapped_pages;
67 struct trans_rpage_info *rpinfo;
68
69 *pdata_off = (__force size_t)req->tc->pubuf & (PAGE_SIZE-1);
70 56
71 if (*pdata_off) 57int p9_payload_gup(char *data, int *nr_pages, struct page **pages, int write)
72 first_page_bytes = min(((size_t)PAGE_SIZE - *pdata_off), 58{
73 req->tc->pbuf_size); 59 int nr_mapped_pages;
74 60
75 rpinfo = req->tc->private; 61 nr_mapped_pages = get_user_pages_fast((unsigned long)data,
76 pdata_mapped_pages = get_user_pages_fast((unsigned long)req->tc->pubuf, 62 *nr_pages, write, pages);
77 nr_pages, rw, &rpinfo->rp_data[0]); 63 if (nr_mapped_pages <= 0)
78 if (pdata_mapped_pages <= 0) 64 return nr_mapped_pages;
79 return pdata_mapped_pages;
80 65
81 rpinfo->rp_nr_pages = pdata_mapped_pages; 66 *nr_pages = nr_mapped_pages;
82 if (*pdata_off) {
83 *pdata_len = first_page_bytes;
84 *pdata_len += min((req->tc->pbuf_size - *pdata_len),
85 ((size_t)pdata_mapped_pages - 1) << PAGE_SHIFT);
86 } else {
87 *pdata_len = min(req->tc->pbuf_size,
88 (size_t)pdata_mapped_pages << PAGE_SHIFT);
89 }
90 return 0; 67 return 0;
91} 68}
92EXPORT_SYMBOL(p9_payload_gup); 69EXPORT_SYMBOL(p9_payload_gup);