diff options
Diffstat (limited to 'net/9p/trans_common.c')
-rw-r--r-- | net/9p/trans_common.c | 53 |
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 | */ |
26 | void | 25 | void p9_release_pages(struct page **pages, int nr_pages) |
27 | p9_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 | } |
36 | EXPORT_SYMBOL(p9_release_req_pages); | 33 | EXPORT_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 | */ |
41 | int | 38 | int p9_nr_pages(char *data, int len) |
42 | p9_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 | } |
50 | EXPORT_SYMBOL(p9_nr_pages); | 45 | EXPORT_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 | */ |
61 | int | ||
62 | p9_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) | 57 | int 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 | } |
92 | EXPORT_SYMBOL(p9_payload_gup); | 69 | EXPORT_SYMBOL(p9_payload_gup); |