Signed-off-by: Venkateswararao Jujjuri <jvrao@xxxxxxxxxxxxxxxxxx> --- net/9p/Makefile | 1 + net/9p/trans_common.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ net/9p/trans_common.h | 26 ++++++++++++++ 3 files changed, 115 insertions(+), 0 deletions(-) create mode 100644 net/9p/trans_common.c create mode 100644 net/9p/trans_common.h diff --git a/net/9p/Makefile b/net/9p/Makefile index 198a640..a0874cc 100644 --- a/net/9p/Makefile +++ b/net/9p/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_NET_9P_RDMA) += 9pnet_rdma.o util.o \ protocol.o \ trans_fd.o \ + trans_common.o \ 9pnet_virtio-objs := \ trans_virtio.o \ diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c new file mode 100644 index 0000000..dad57d2 --- /dev/null +++ b/net/9p/trans_common.c @@ -0,0 +1,88 @@ +/* + * Copyright IBM Corporation, 2010 + * Author Venkateswararao Jujjuri <jvrao@xxxxxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include <linux/slab.h> +#include <net/9p/9p.h> +#include <net/9p/client.h> +#include <linux/scatterlist.h> +#include "trans_common.h" + +/** + * p9_release_req_pages - Release pages after the transaction. + * @*private: PDU's private page of type virtio_rpage_info_t + */ +void +p9_release_req_pages(void *private) +{ + virtio_rpage_info_t *vpinfo = private; + int i = 0; + + while (vpinfo->vp_data[i] && vpinfo->vp_nr_pages--) { + put_page(vpinfo->vp_data[i]); + i++; + } +} + +/** + * payload_gup - Calculates number of pages that needs to be pinned and + * pins them ehter for read/write through get_user_pages_fast(). + */ +int +payload_gup(struct p9_req_t *req, size_t *pdata_off, int *pdata_len, u8 rw) +{ + int nr_pages; + uint32_t first_page_bytes = 0; + uint32_t pdata_mapped_pages; + virtio_rpage_info_t *rpinfo; + + nr_pages = req->tc->pbuf_size >> PAGE_SHIFT; + *pdata_off = (size_t)req->tc->pbuf & (PAGE_SIZE-1); + + if (*pdata_off) + first_page_bytes = min((PAGE_SIZE - *pdata_off), + req->tc->pbuf_size); + + if (req->tc->pbuf_size - (first_page_bytes + (nr_pages << PAGE_SHIFT))){ + /* trailing partial page */ + nr_pages++; + } + if (first_page_bytes) { + /* leading partial page */ + nr_pages++; + } + /* TODO: Use buffer on PDU instead of allocating */ + rpinfo = kmalloc(sizeof(virtio_rpage_info_t) + + sizeof(struct page *) * nr_pages, GFP_KERNEL); + req->tc->private = (void *)rpinfo; + pdata_mapped_pages = get_user_pages_fast((unsigned long)req->tc->pbuf, + nr_pages, rw, &rpinfo->vp_data[0]); + + if (pdata_mapped_pages < 0) { + printk("get_user_pages_fast failed:%d udata:%p" "nr_pages:%d\n", + pdata_mapped_pages, req->tc->pbuf, nr_pages); + pdata_mapped_pages = 0; + kfree(rpinfo); + return -EIO; + } + rpinfo->vp_nr_pages = pdata_mapped_pages; + if (*pdata_off) { + *pdata_len = first_page_bytes; + *pdata_len += min((req->tc->pbuf_size - *pdata_len), + ((size_t)pdata_mapped_pages - 1) << PAGE_SHIFT); + } else { + *pdata_len = min (req->tc->pbuf_size, + (size_t)pdata_mapped_pages << PAGE_SHIFT); + } + return 0; +} diff --git a/net/9p/trans_common.h b/net/9p/trans_common.h new file mode 100644 index 0000000..8c85392 --- /dev/null +++ b/net/9p/trans_common.h @@ -0,0 +1,26 @@ +/* + * Copyright IBM Corporation, 2010 + * Author Venkateswararao Jujjuri <jvrao@xxxxxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +/** + * struct virtio_rpage_info - To store mapped page information in PDU. + * @vp_nr_pages: Number of mapped pages + * @vp_data: Array of page pointers + */ +typedef struct virtio_rpage_info { + int vp_nr_pages; + struct page *vp_data[0]; +} virtio_rpage_info_t; + +void p9_release_req_pages(void *); +int payload_gup(struct p9_req_t *, size_t *, int *, u8); -- 1.6.5.2 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html