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 <pshilov@microsoft.com>
This commit is contained in:
parent
9b7c18a2d4
commit
d70b9104b1
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue