Commit 8e7360f6 authored by Long Li's avatar Long Li Committed by Steve French

CIFS: Add support for direct pages in wdata

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

wdata is 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 1dbe3466
...@@ -1211,7 +1211,7 @@ struct cifs_writedata { ...@@ -1211,7 +1211,7 @@ struct cifs_writedata {
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;
}; };
/* /*
......
...@@ -533,6 +533,8 @@ int cifs_async_writev(struct cifs_writedata *wdata, ...@@ -533,6 +533,8 @@ int cifs_async_writev(struct cifs_writedata *wdata,
void cifs_writev_complete(struct work_struct *work); void cifs_writev_complete(struct work_struct *work);
struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages,
work_func_t complete); work_func_t complete);
struct cifs_writedata *cifs_writedata_direct_alloc(struct page **pages,
work_func_t complete);
void cifs_writedata_release(struct kref *refcount); void cifs_writedata_release(struct kref *refcount);
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, struct cifs_sb_info *cifs_sb,
......
...@@ -1952,6 +1952,7 @@ cifs_writedata_release(struct kref *refcount) ...@@ -1952,6 +1952,7 @@ cifs_writedata_release(struct kref *refcount)
if (wdata->cfile) if (wdata->cfile)
cifsFileInfo_put(wdata->cfile); cifsFileInfo_put(wdata->cfile);
kvfree(wdata->pages);
kfree(wdata); kfree(wdata);
} }
...@@ -2074,13 +2075,23 @@ cifs_writev_complete(struct work_struct *work) ...@@ -2074,13 +2075,23 @@ cifs_writev_complete(struct work_struct *work)
struct cifs_writedata * struct cifs_writedata *
cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
{
struct page **pages =
kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
if (pages)
return cifs_writedata_direct_alloc(pages, complete);
return NULL;
}
struct cifs_writedata *
cifs_writedata_direct_alloc(struct page **pages, work_func_t complete)
{ {
struct cifs_writedata *wdata; struct cifs_writedata *wdata;
/* writedata + number of page pointers */ wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
wdata = kzalloc(sizeof(*wdata) +
sizeof(struct page *) * nr_pages, GFP_NOFS);
if (wdata != NULL) { if (wdata != NULL) {
wdata->pages = pages;
kref_init(&wdata->refcount); kref_init(&wdata->refcount);
INIT_LIST_HEAD(&wdata->list); INIT_LIST_HEAD(&wdata->list);
init_completion(&wdata->done); init_completion(&wdata->done);
......
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