|
@@ -850,11 +850,11 @@ static int fuse_readpages_fill(void *_data, struct page *page)
|
|
|
fuse_wait_on_page_writeback(inode, page->index);
|
|
|
|
|
|
if (req->num_pages &&
|
|
|
- (req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
|
|
|
+ (req->num_pages == fc->max_pages ||
|
|
|
(req->num_pages + 1) * PAGE_SIZE > fc->max_read ||
|
|
|
req->pages[req->num_pages - 1]->index + 1 != page->index)) {
|
|
|
- int nr_alloc = min_t(unsigned, data->nr_pages,
|
|
|
- FUSE_MAX_PAGES_PER_REQ);
|
|
|
+ unsigned int nr_alloc = min_t(unsigned int, data->nr_pages,
|
|
|
+ fc->max_pages);
|
|
|
fuse_send_readpages(req, data->file);
|
|
|
if (fc->async_read)
|
|
|
req = fuse_get_req_for_background(fc, nr_alloc);
|
|
@@ -889,7 +889,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
|
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
|
struct fuse_fill_data data;
|
|
|
int err;
|
|
|
- int nr_alloc = min_t(unsigned, nr_pages, FUSE_MAX_PAGES_PER_REQ);
|
|
|
+ unsigned int nr_alloc = min_t(unsigned int, nr_pages, fc->max_pages);
|
|
|
|
|
|
err = -EIO;
|
|
|
if (is_bad_inode(inode))
|
|
@@ -1104,12 +1104,13 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
|
|
|
return count > 0 ? count : err;
|
|
|
}
|
|
|
|
|
|
-static inline unsigned fuse_wr_pages(loff_t pos, size_t len)
|
|
|
+static inline unsigned int fuse_wr_pages(loff_t pos, size_t len,
|
|
|
+ unsigned int max_pages)
|
|
|
{
|
|
|
- return min_t(unsigned,
|
|
|
+ return min_t(unsigned int,
|
|
|
((pos + len - 1) >> PAGE_SHIFT) -
|
|
|
(pos >> PAGE_SHIFT) + 1,
|
|
|
- FUSE_MAX_PAGES_PER_REQ);
|
|
|
+ max_pages);
|
|
|
}
|
|
|
|
|
|
static ssize_t fuse_perform_write(struct kiocb *iocb,
|
|
@@ -1131,7 +1132,8 @@ static ssize_t fuse_perform_write(struct kiocb *iocb,
|
|
|
do {
|
|
|
struct fuse_req *req;
|
|
|
ssize_t count;
|
|
|
- unsigned nr_pages = fuse_wr_pages(pos, iov_iter_count(ii));
|
|
|
+ unsigned int nr_pages = fuse_wr_pages(pos, iov_iter_count(ii),
|
|
|
+ fc->max_pages);
|
|
|
|
|
|
req = fuse_get_req(fc, nr_pages);
|
|
|
if (IS_ERR(req)) {
|
|
@@ -1321,11 +1323,6 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
|
|
|
return ret < 0 ? ret : 0;
|
|
|
}
|
|
|
|
|
|
-static inline int fuse_iter_npages(const struct iov_iter *ii_p)
|
|
|
-{
|
|
|
- return iov_iter_npages(ii_p, FUSE_MAX_PAGES_PER_REQ);
|
|
|
-}
|
|
|
-
|
|
|
ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
|
|
|
loff_t *ppos, int flags)
|
|
|
{
|
|
@@ -1345,9 +1342,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
|
|
|
int err = 0;
|
|
|
|
|
|
if (io->async)
|
|
|
- req = fuse_get_req_for_background(fc, fuse_iter_npages(iter));
|
|
|
+ req = fuse_get_req_for_background(fc, iov_iter_npages(iter,
|
|
|
+ fc->max_pages));
|
|
|
else
|
|
|
- req = fuse_get_req(fc, fuse_iter_npages(iter));
|
|
|
+ req = fuse_get_req(fc, iov_iter_npages(iter, fc->max_pages));
|
|
|
if (IS_ERR(req))
|
|
|
return PTR_ERR(req);
|
|
|
|
|
@@ -1392,9 +1390,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
|
|
|
fuse_put_request(fc, req);
|
|
|
if (io->async)
|
|
|
req = fuse_get_req_for_background(fc,
|
|
|
- fuse_iter_npages(iter));
|
|
|
+ iov_iter_npages(iter, fc->max_pages));
|
|
|
else
|
|
|
- req = fuse_get_req(fc, fuse_iter_npages(iter));
|
|
|
+ req = fuse_get_req(fc, iov_iter_npages(iter,
|
|
|
+ fc->max_pages));
|
|
|
if (IS_ERR(req))
|
|
|
break;
|
|
|
}
|
|
@@ -1823,7 +1822,7 @@ static int fuse_writepages_fill(struct page *page,
|
|
|
is_writeback = fuse_page_is_writeback(inode, page->index);
|
|
|
|
|
|
if (req && req->num_pages &&
|
|
|
- (is_writeback || req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
|
|
|
+ (is_writeback || req->num_pages == fc->max_pages ||
|
|
|
(req->num_pages + 1) * PAGE_SIZE > fc->max_write ||
|
|
|
data->orig_pages[req->num_pages - 1]->index + 1 != page->index)) {
|
|
|
fuse_writepages_send(data);
|
|
@@ -1851,7 +1850,7 @@ static int fuse_writepages_fill(struct page *page,
|
|
|
struct fuse_inode *fi = get_fuse_inode(inode);
|
|
|
|
|
|
err = -ENOMEM;
|
|
|
- req = fuse_request_alloc_nofs(FUSE_MAX_PAGES_PER_REQ);
|
|
|
+ req = fuse_request_alloc_nofs(fc->max_pages);
|
|
|
if (!req) {
|
|
|
__free_page(tmp_page);
|
|
|
goto out_unlock;
|
|
@@ -1908,6 +1907,7 @@ static int fuse_writepages(struct address_space *mapping,
|
|
|
struct writeback_control *wbc)
|
|
|
{
|
|
|
struct inode *inode = mapping->host;
|
|
|
+ struct fuse_conn *fc = get_fuse_conn(inode);
|
|
|
struct fuse_fill_wb_data data;
|
|
|
int err;
|
|
|
|
|
@@ -1920,7 +1920,7 @@ static int fuse_writepages(struct address_space *mapping,
|
|
|
data.ff = NULL;
|
|
|
|
|
|
err = -ENOMEM;
|
|
|
- data.orig_pages = kcalloc(FUSE_MAX_PAGES_PER_REQ,
|
|
|
+ data.orig_pages = kcalloc(fc->max_pages,
|
|
|
sizeof(struct page *),
|
|
|
GFP_NOFS);
|
|
|
if (!data.orig_pages)
|
|
@@ -2391,10 +2391,11 @@ static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src,
|
|
|
}
|
|
|
|
|
|
/* Make sure iov_length() won't overflow */
|
|
|
-static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
|
|
|
+static int fuse_verify_ioctl_iov(struct fuse_conn *fc, struct iovec *iov,
|
|
|
+ size_t count)
|
|
|
{
|
|
|
size_t n;
|
|
|
- u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
|
|
|
+ u32 max = fc->max_pages << PAGE_SHIFT;
|
|
|
|
|
|
for (n = 0; n < count; n++, iov++) {
|
|
|
if (iov->iov_len > (size_t) max)
|
|
@@ -2518,7 +2519,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
|
|
BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE);
|
|
|
|
|
|
err = -ENOMEM;
|
|
|
- pages = kcalloc(FUSE_MAX_PAGES_PER_REQ, sizeof(pages[0]), GFP_KERNEL);
|
|
|
+ pages = kcalloc(fc->max_pages, sizeof(pages[0]), GFP_KERNEL);
|
|
|
iov_page = (struct iovec *) __get_free_page(GFP_KERNEL);
|
|
|
if (!pages || !iov_page)
|
|
|
goto out;
|
|
@@ -2557,7 +2558,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
|
|
|
|
|
/* make sure there are enough buffer pages and init request with them */
|
|
|
err = -ENOMEM;
|
|
|
- if (max_pages > FUSE_MAX_PAGES_PER_REQ)
|
|
|
+ if (max_pages > fc->max_pages)
|
|
|
goto out;
|
|
|
while (num_pages < max_pages) {
|
|
|
pages[num_pages] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
|
|
@@ -2644,11 +2645,11 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
|
|
in_iov = iov_page;
|
|
|
out_iov = in_iov + in_iovs;
|
|
|
|
|
|
- err = fuse_verify_ioctl_iov(in_iov, in_iovs);
|
|
|
+ err = fuse_verify_ioctl_iov(fc, in_iov, in_iovs);
|
|
|
if (err)
|
|
|
goto out;
|
|
|
|
|
|
- err = fuse_verify_ioctl_iov(out_iov, out_iovs);
|
|
|
+ err = fuse_verify_ioctl_iov(fc, out_iov, out_iovs);
|
|
|
if (err)
|
|
|
goto out;
|
|
|
|
|
@@ -2839,9 +2840,9 @@ static void fuse_do_truncate(struct file *file)
|
|
|
fuse_do_setattr(file_dentry(file), &attr, file);
|
|
|
}
|
|
|
|
|
|
-static inline loff_t fuse_round_up(loff_t off)
|
|
|
+static inline loff_t fuse_round_up(struct fuse_conn *fc, loff_t off)
|
|
|
{
|
|
|
- return round_up(off, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
|
|
|
+ return round_up(off, fc->max_pages << PAGE_SHIFT);
|
|
|
}
|
|
|
|
|
|
static ssize_t
|
|
@@ -2870,7 +2871,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
|
|
|
if (async_dio && iov_iter_rw(iter) != WRITE && offset + count > i_size) {
|
|
|
if (offset >= i_size)
|
|
|
return 0;
|
|
|
- iov_iter_truncate(iter, fuse_round_up(i_size - offset));
|
|
|
+ iov_iter_truncate(iter, fuse_round_up(ff->fc, i_size - offset));
|
|
|
count = iov_iter_count(iter);
|
|
|
}
|
|
|
|