From: Pavel Shilovsky Date: Fri, 18 Nov 2016 00:20:18 +0000 (-0800) Subject: CIFS: Add copy into pages callback for a read operation X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=d70b9104b1ca586f73aaf59426756cec3325a40e;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git CIFS: Add copy into pages callback for a read operation Since we have two different types of reads (pagecache and direct) we need to process such responses differently after decryption of a packet. The change allows to specify a callback that copies a read payload data into preallocated pages. Signed-off-by: Pavel Shilovsky --- diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 8a04a013a4ac..d6172c8b61bf 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1129,6 +1129,9 @@ struct cifs_readdata { int (*read_into_pages)(struct TCP_Server_Info *server, struct cifs_readdata *rdata, unsigned int len); + int (*copy_into_pages)(struct TCP_Server_Info *server, + struct cifs_readdata *rdata, + struct iov_iter *iter); struct kvec iov[2]; unsigned int pagesz; unsigned int tailsz; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1cd0e2eefc66..98dc842e7245 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2911,8 +2911,9 @@ cifs_uncached_readv_complete(struct work_struct *work) } static int -cifs_uncached_read_into_pages(struct TCP_Server_Info *server, - struct cifs_readdata *rdata, unsigned int len) +uncached_fill_pages(struct TCP_Server_Info *server, + struct cifs_readdata *rdata, struct iov_iter *iter, + unsigned int len) { int result = 0; unsigned int i; @@ -2941,7 +2942,10 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server, rdata->tailsz = len; len = 0; } - result = cifs_read_page_from_socket(server, page, n); + if (iter) + result = copy_page_from_iter(page, 0, n, iter); + else + result = cifs_read_page_from_socket(server, page, n); if (result < 0) break; @@ -2952,6 +2956,21 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server, rdata->got_bytes : result; } +static int +cifs_uncached_read_into_pages(struct TCP_Server_Info *server, + struct cifs_readdata *rdata, unsigned int len) +{ + return uncached_fill_pages(server, rdata, NULL, len); +} + +static int +cifs_uncached_copy_into_pages(struct TCP_Server_Info *server, + struct cifs_readdata *rdata, + struct iov_iter *iter) +{ + return uncached_fill_pages(server, rdata, iter, iter->count); +} + static int cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, struct cifs_sb_info *cifs_sb, struct list_head *rdata_list) @@ -2999,6 +3018,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, rdata->pid = pid; rdata->pagesz = PAGE_SIZE; rdata->read_into_pages = cifs_uncached_read_into_pages; + rdata->copy_into_pages = cifs_uncached_copy_into_pages; rdata->credits = credits; if (!rdata->cfile->invalidHandle || @@ -3349,8 +3369,9 @@ cifs_readv_complete(struct work_struct *work) } static int -cifs_readpages_read_into_pages(struct TCP_Server_Info *server, - struct cifs_readdata *rdata, unsigned int len) +readpages_fill_pages(struct TCP_Server_Info *server, + struct cifs_readdata *rdata, struct iov_iter *iter, + unsigned int len) { int result = 0; unsigned int i; @@ -3404,7 +3425,10 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, continue; } - result = cifs_read_page_from_socket(server, page, n); + if (iter) + result = copy_page_from_iter(page, 0, n, iter); + else + result = cifs_read_page_from_socket(server, page, n); if (result < 0) break; @@ -3415,6 +3439,21 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, rdata->got_bytes : result; } +static int +cifs_readpages_read_into_pages(struct TCP_Server_Info *server, + struct cifs_readdata *rdata, unsigned int len) +{ + return readpages_fill_pages(server, rdata, NULL, len); +} + +static int +cifs_readpages_copy_into_pages(struct TCP_Server_Info *server, + struct cifs_readdata *rdata, + struct iov_iter *iter) +{ + return readpages_fill_pages(server, rdata, iter, iter->count); +} + static int readpages_get_pages(struct address_space *mapping, struct list_head *page_list, unsigned int rsize, struct list_head *tmplist, @@ -3569,6 +3608,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, rdata->pid = pid; rdata->pagesz = PAGE_SIZE; rdata->read_into_pages = cifs_readpages_read_into_pages; + rdata->copy_into_pages = cifs_readpages_copy_into_pages; rdata->credits = credits; list_for_each_entry_safe(page, tpage, &tmplist, lru) {