|
@@ -555,6 +555,7 @@ static int fuse_readpage(struct file *file, struct page *page)
|
|
|
req->out.argpages = 1;
|
|
|
req->num_pages = 1;
|
|
|
req->pages[0] = page;
|
|
|
+ req->page_descs[0].length = count;
|
|
|
num_read = fuse_send_read(req, file, pos, count, NULL);
|
|
|
err = req->out.h.error;
|
|
|
fuse_put_request(fc, req);
|
|
@@ -674,6 +675,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
|
|
|
|
|
|
page_cache_get(page);
|
|
|
req->pages[req->num_pages] = page;
|
|
|
+ req->page_descs[req->num_pages].length = PAGE_SIZE;
|
|
|
req->num_pages++;
|
|
|
data->nr_pages--;
|
|
|
return 0;
|
|
@@ -869,6 +871,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
|
|
|
|
|
|
err = 0;
|
|
|
req->pages[req->num_pages] = page;
|
|
|
+ req->page_descs[req->num_pages].length = tmp;
|
|
|
req->num_pages++;
|
|
|
|
|
|
iov_iter_advance(ii, tmp);
|
|
@@ -1044,6 +1047,15 @@ static void fuse_release_user_pages(struct fuse_req *req, int write)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static inline void fuse_page_descs_length_init(struct fuse_req *req)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < req->num_pages; i++)
|
|
|
+ req->page_descs[i].length = PAGE_SIZE -
|
|
|
+ req->page_descs[i].offset;
|
|
|
+}
|
|
|
+
|
|
|
static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
|
|
|
size_t *nbytesp, int write)
|
|
|
{
|
|
@@ -1071,6 +1083,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
|
|
|
|
|
|
req->num_pages = npages;
|
|
|
req->page_descs[0].offset = offset;
|
|
|
+ fuse_page_descs_length_init(req);
|
|
|
|
|
|
if (write)
|
|
|
req->in.argpages = 1;
|
|
@@ -1078,6 +1091,11 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
|
|
|
req->out.argpages = 1;
|
|
|
|
|
|
nbytes = (req->num_pages << PAGE_SHIFT) - req->page_descs[0].offset;
|
|
|
+
|
|
|
+ if (*nbytesp < nbytes)
|
|
|
+ req->page_descs[req->num_pages - 1].length -=
|
|
|
+ nbytes - *nbytesp;
|
|
|
+
|
|
|
*nbytesp = min(*nbytesp, nbytes);
|
|
|
|
|
|
return 0;
|
|
@@ -1315,6 +1333,7 @@ static int fuse_writepage_locked(struct page *page)
|
|
|
req->num_pages = 1;
|
|
|
req->pages[0] = tmp_page;
|
|
|
req->page_descs[0].offset = 0;
|
|
|
+ req->page_descs[0].length = PAGE_SIZE;
|
|
|
req->end = fuse_writepage_end;
|
|
|
req->inode = inode;
|
|
|
|
|
@@ -1902,6 +1921,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
|
|
}
|
|
|
memcpy(req->pages, pages, sizeof(req->pages[0]) * num_pages);
|
|
|
req->num_pages = num_pages;
|
|
|
+ fuse_page_descs_length_init(req);
|
|
|
|
|
|
/* okay, let's send it to the client */
|
|
|
req->in.h.opcode = FUSE_IOCTL;
|