Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;
+46 −6
Original line number Diff line number Diff line
@@ -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,6 +2942,9 @@ cifs_uncached_read_into_pages(struct TCP_Server_Info *server,
			rdata->tailsz = len;
			len = 0;
		}
		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,6 +3425,9 @@ cifs_readpages_read_into_pages(struct TCP_Server_Info *server,
			continue;
		}

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