From: Brian F. <bf...@re...> - 2012-09-25 16:46:44
|
On 09/19/2012 12:32 PM, Maxim Patlasov wrote: > The ability to save page pointers along with lengths and offsets in fuse_req > will be useful to cover several iovec-s with a single fuse_req. > > Per-request page_offset is removed because anybody who need it can use > req->page_descs[0].offset instead. > > Signed-off-by: Maxim Patlasov <mpa...@pa...> > --- > fs/fuse/dev.c | 27 +++++++++++++++++++-------- > fs/fuse/file.c | 10 +++++----- > fs/fuse/fuse_i.h | 15 ++++++++++++--- > 3 files changed, 36 insertions(+), 16 deletions(-) > > diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c > index b241a7d..ea63d39 100644 > --- a/fs/fuse/dev.c > +++ b/fs/fuse/dev.c > @@ -35,14 +35,16 @@ static struct fuse_conn *fuse_get_conn(struct file *file) > } > > static void fuse_request_init(struct fuse_req *req, struct page **pages, > - unsigned npages) > + struct page_desc *page_descs, unsigned npages) > { > memset(req, 0, sizeof(*req)); > + memset(page_descs, 0, sizeof(*page_descs) * npages); > INIT_LIST_HEAD(&req->list); > INIT_LIST_HEAD(&req->intr_entry); > init_waitqueue_head(&req->waitq); > atomic_set(&req->count, 1); > req->pages = pages; > + req->page_descs = page_descs; > req->max_pages = npages; > } > > @@ -51,18 +53,25 @@ static struct fuse_req *__fuse_request_alloc(int npages, gfp_t flags) > struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags); > if (req) { > struct page **pages; > + struct page_desc *page_descs; > > - if (npages <= FUSE_REQ_INLINE_PAGES) > + if (npages <= FUSE_REQ_INLINE_PAGES) { > pages = req->inline_pages; > - else > + page_descs = req->inline_page_descs; > + } else { > pages = kmalloc(sizeof(struct page *) * npages, flags); > + page_descs = kmalloc(sizeof(struct page_desc) * npages, > + flags); > + } > > - if (!pages) { > + if (!pages || !page_descs) { > + kfree(pages); > + kfree(page_descs); > kmem_cache_free(fuse_req_cachep, req); > return NULL; > } > > - fuse_request_init(req, pages, npages); > + fuse_request_init(req, pages, page_descs, npages); > } > return req; > } > @@ -82,6 +91,8 @@ void fuse_request_free(struct fuse_req *req) > { > if (req->pages != req->inline_pages) > kfree(req->pages); > + if (req->page_descs != req->inline_page_descs) > + kfree(req->page_descs); > kmem_cache_free(fuse_req_cachep, req); > } > > @@ -186,7 +197,7 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) > struct fuse_file *ff = file->private_data; > > spin_lock(&fc->lock); > - fuse_request_init(req, req->pages, req->max_pages); > + fuse_request_init(req, req->pages, req->page_descs, req->max_pages); > BUG_ON(ff->reserved_req); > ff->reserved_req = req; > wake_up_all(&fc->reserved_req_waitq); > @@ -877,7 +888,7 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, > { > unsigned i; > struct fuse_req *req = cs->req; > - unsigned offset = req->page_offset; > + unsigned offset = req->page_descs[0].offset; > unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset); > > for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { > @@ -1585,7 +1596,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, > req->in.h.nodeid = outarg->nodeid; > req->in.numargs = 2; > req->in.argpages = 1; > - req->page_offset = offset; > + req->page_descs[0].offset = offset; > req->end = fuse_retrieve_end; > > index = outarg->offset >> PAGE_CACHE_SHIFT; > diff --git a/fs/fuse/file.c b/fs/fuse/file.c > index 08899a6..b68cf3b 100644 > --- a/fs/fuse/file.c > +++ b/fs/fuse/file.c > @@ -798,7 +798,7 @@ static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file, > > res = fuse_send_write(req, file, pos, count, NULL); > > - offset = req->page_offset; > + offset = req->page_descs[0].offset; > count = res; > for (i = 0; i < req->num_pages; i++) { > struct page *page = req->pages[i]; > @@ -829,7 +829,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req, > int err; > > req->in.argpages = 1; > - req->page_offset = offset; > + req->page_descs[0].offset = offset; > > do { > size_t tmp; > @@ -1070,14 +1070,14 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf, > return npages; > > req->num_pages = npages; > - req->page_offset = offset; > + req->page_descs[0].offset = offset; > > if (write) > req->in.argpages = 1; > else > req->out.argpages = 1; > > - nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset; > + nbytes = (req->num_pages << PAGE_SHIFT) - req->page_descs[0].offset; > *nbytesp = min(*nbytesp, nbytes); > > return 0; > @@ -1314,7 +1314,7 @@ static int fuse_writepage_locked(struct page *page) > req->in.argpages = 1; > req->num_pages = 1; > req->pages[0] = tmp_page; > - req->page_offset = 0; > + req->page_descs[0].offset = 0; > req->end = fuse_writepage_end; > req->inode = inode; > > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h > index fd69d62..fbf9379 100644 > --- a/fs/fuse/fuse_i.h > +++ b/fs/fuse/fuse_i.h > @@ -203,6 +203,12 @@ struct fuse_out { > struct fuse_arg args[3]; > }; > > +/** FUSE page descriptor */ > +struct page_desc { > + unsigned int length; > + unsigned int offset; > +}; > + struct fuse_page_desc ? > /** The request state */ > enum fuse_req_state { > FUSE_REQ_INIT = 0, > @@ -296,18 +302,21 @@ struct fuse_req { > /** page vector */ > struct page **pages; > > + /** page-descriptor vector */ > + struct page_desc *page_descs; > + > /** size of the 'pages' array */ > unsigned max_pages; > > /** inline page vector */ > struct page *inline_pages[FUSE_REQ_INLINE_PAGES]; > > + /** inline page-descriptor vector */ > + struct page_desc inline_page_descs[FUSE_REQ_INLINE_PAGES]; > + > /** number of pages in vector */ > unsigned num_pages; > More aesthetic than anything I suppose, but any reason not to fold the page pointers into the descriptor? It seems like it would be slightly more simple. Brian > - /** offset of data on first page */ > - unsigned page_offset; > - > /** File used in the request (or NULL) */ > struct fuse_file *ff; > > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > fuse-devel mailing list > fus...@li... > https://lists.sourceforge.net/lists/listinfo/fuse-devel > |