Commit d70b9104 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French

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: default avatarPavel Shilovsky <pshilov@microsoft.com>
parent 9b7c18a2
...@@ -1129,6 +1129,9 @@ struct cifs_readdata { ...@@ -1129,6 +1129,9 @@ struct cifs_readdata {
int (*read_into_pages)(struct TCP_Server_Info *server, int (*read_into_pages)(struct TCP_Server_Info *server,
struct cifs_readdata *rdata, struct cifs_readdata *rdata,
unsigned int len); unsigned int len);
int (*copy_into_pages)(struct TCP_Server_Info *server,
struct cifs_readdata *rdata,
struct iov_iter *iter);
struct kvec iov[2]; struct kvec iov[2];
unsigned int pagesz; unsigned int pagesz;
unsigned int tailsz; unsigned int tailsz;
......
...@@ -2911,8 +2911,9 @@ cifs_uncached_readv_complete(struct work_struct *work) ...@@ -2911,8 +2911,9 @@ cifs_uncached_readv_complete(struct work_struct *work)
} }
static int static int
cifs_uncached_read_into_pages(struct TCP_Server_Info *server, uncached_fill_pages(struct TCP_Server_Info *server,
struct cifs_readdata *rdata, unsigned int len) struct cifs_readdata *rdata, struct iov_iter *iter,
unsigned int len)
{ {
int result = 0; int result = 0;
unsigned int i; unsigned int i;
...@@ -2941,7 +2942,10 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server, ...@@ -2941,7 +2942,10 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
rdata->tailsz = len; rdata->tailsz = len;
len = 0; 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) if (result < 0)
break; break;
...@@ -2952,6 +2956,21 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server, ...@@ -2952,6 +2956,21 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
rdata->got_bytes : result; 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 static int
cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, 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) 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, ...@@ -2999,6 +3018,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
rdata->pid = pid; rdata->pid = pid;
rdata->pagesz = PAGE_SIZE; rdata->pagesz = PAGE_SIZE;
rdata->read_into_pages = cifs_uncached_read_into_pages; rdata->read_into_pages = cifs_uncached_read_into_pages;
rdata->copy_into_pages = cifs_uncached_copy_into_pages;
rdata->credits = credits; rdata->credits = credits;
if (!rdata->cfile->invalidHandle || if (!rdata->cfile->invalidHandle ||
...@@ -3349,8 +3369,9 @@ cifs_readv_complete(struct work_struct *work) ...@@ -3349,8 +3369,9 @@ cifs_readv_complete(struct work_struct *work)
} }
static int static int
cifs_readpages_read_into_pages(struct TCP_Server_Info *server, readpages_fill_pages(struct TCP_Server_Info *server,
struct cifs_readdata *rdata, unsigned int len) struct cifs_readdata *rdata, struct iov_iter *iter,
unsigned int len)
{ {
int result = 0; int result = 0;
unsigned int i; unsigned int i;
...@@ -3404,7 +3425,10 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, ...@@ -3404,7 +3425,10 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server,
continue; 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) if (result < 0)
break; break;
...@@ -3415,6 +3439,21 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server, ...@@ -3415,6 +3439,21 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server,
rdata->got_bytes : result; 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 static int
readpages_get_pages(struct address_space *mapping, struct list_head *page_list, readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
unsigned int rsize, struct list_head *tmplist, unsigned int rsize, struct list_head *tmplist,
...@@ -3569,6 +3608,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, ...@@ -3569,6 +3608,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
rdata->pid = pid; rdata->pid = pid;
rdata->pagesz = PAGE_SIZE; rdata->pagesz = PAGE_SIZE;
rdata->read_into_pages = cifs_readpages_read_into_pages; rdata->read_into_pages = cifs_readpages_read_into_pages;
rdata->copy_into_pages = cifs_readpages_copy_into_pages;
rdata->credits = credits; rdata->credits = credits;
list_for_each_entry_safe(page, tpage, &tmplist, lru) { list_for_each_entry_safe(page, tpage, &tmplist, lru) {
......
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