diff options
author | Long Li <longli@microsoft.com> | 2018-05-30 21:47:56 +0200 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2018-06-03 01:36:26 +0200 |
commit | 8e7360f67e75e06f3ea144354243728fb8f54c57 (patch) | |
tree | a17499125a7b605275034d9dbbdf76911c1b5a0d /fs/cifs/cifssmb.c | |
parent | CIFS: Use offset when reading pages (diff) | |
download | linux-8e7360f67e75e06f3ea144354243728fb8f54c57.tar.xz linux-8e7360f67e75e06f3ea144354243728fb8f54c57.zip |
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: Long Li <longli@microsoft.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c8e42785d261..5aca336642c0 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1952,6 +1952,7 @@ cifs_writedata_release(struct kref *refcount) if (wdata->cfile) cifsFileInfo_put(wdata->cfile); + kvfree(wdata->pages); kfree(wdata); } @@ -2075,12 +2076,22 @@ cifs_writev_complete(struct work_struct *work) struct cifs_writedata * 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; - /* writedata + number of page pointers */ - wdata = kzalloc(sizeof(*wdata) + - sizeof(struct page *) * nr_pages, GFP_NOFS); + wdata = kzalloc(sizeof(*wdata), GFP_NOFS); if (wdata != NULL) { + wdata->pages = pages; kref_init(&wdata->refcount); INIT_LIST_HEAD(&wdata->list); init_completion(&wdata->done); |