Commit f9f5aca1 authored by Long Li's avatar Long Li Committed by Steve French

CIFS: Add support for direct pages in rdata

Add a function to allocate rdata without allocating pages for data
transfer. This gives the caller an option to pass a number of pages
that point to the data buffer.

rdata is still reponsible for free those pages after it's done.
Signed-off-by: default avatarLong Li <longli@microsoft.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 8ce79ec3
...@@ -1185,7 +1185,7 @@ struct cifs_readdata { ...@@ -1185,7 +1185,7 @@ struct cifs_readdata {
unsigned int tailsz; unsigned int tailsz;
unsigned int credits; unsigned int credits;
unsigned int nr_pages; unsigned int nr_pages;
struct page *pages[]; struct page **pages;
}; };
struct cifs_writedata; struct cifs_writedata;
......
...@@ -2880,13 +2880,13 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) ...@@ -2880,13 +2880,13 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
} }
static struct cifs_readdata * static struct cifs_readdata *
cifs_readdata_alloc(unsigned int nr_pages, work_func_t complete) cifs_readdata_direct_alloc(struct page **pages, work_func_t complete)
{ {
struct cifs_readdata *rdata; struct cifs_readdata *rdata;
rdata = kzalloc(sizeof(*rdata) + (sizeof(struct page *) * nr_pages), rdata = kzalloc(sizeof(*rdata), GFP_KERNEL);
GFP_KERNEL);
if (rdata != NULL) { if (rdata != NULL) {
rdata->pages = pages;
kref_init(&rdata->refcount); kref_init(&rdata->refcount);
INIT_LIST_HEAD(&rdata->list); INIT_LIST_HEAD(&rdata->list);
init_completion(&rdata->done); init_completion(&rdata->done);
...@@ -2896,6 +2896,22 @@ cifs_readdata_alloc(unsigned int nr_pages, work_func_t complete) ...@@ -2896,6 +2896,22 @@ cifs_readdata_alloc(unsigned int nr_pages, work_func_t complete)
return rdata; return rdata;
} }
static struct cifs_readdata *
cifs_readdata_alloc(unsigned int nr_pages, work_func_t complete)
{
struct page **pages =
kzalloc(sizeof(struct page *) * nr_pages, GFP_KERNEL);
struct cifs_readdata *ret = NULL;
if (pages) {
ret = cifs_readdata_direct_alloc(pages, complete);
if (!ret)
kfree(pages);
}
return ret;
}
void void
cifs_readdata_release(struct kref *refcount) cifs_readdata_release(struct kref *refcount)
{ {
...@@ -2910,6 +2926,7 @@ cifs_readdata_release(struct kref *refcount) ...@@ -2910,6 +2926,7 @@ cifs_readdata_release(struct kref *refcount)
if (rdata->cfile) if (rdata->cfile)
cifsFileInfo_put(rdata->cfile); cifsFileInfo_put(rdata->cfile);
kvfree(rdata->pages);
kfree(rdata); kfree(rdata);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment