|
@@ -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) {
|