aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorMaxim Patlasov <mpatlasov@parallels.com>2012-10-26 11:48:42 -0400
committerMiklos Szeredi <mszeredi@suse.cz>2013-01-24 10:21:26 -0500
commit4d53dc99baf139e4fa0d395f7658032cc2eb3297 (patch)
tree4709fcfd8631d744abc95195a257b67000e863fa /fs/fuse
parentb111c8c0e3e5e780ae0758fc4c1c376a7c9d5997 (diff)
fuse: rework fuse_retrieve()
The patch reworks fuse_retrieve() to allocate only so many page pointers as needed. The core part of the patch is the following calculation: num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; (thanks Miklos for formula). All other changes are mostly shuffling lines. Signed-off-by: Maxim Patlasov <mpatlasov@parallels.com> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dev.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index ff5e8bed5d88..28d9792de4a2 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1577,13 +1577,24 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
1577 unsigned int num; 1577 unsigned int num;
1578 unsigned int offset; 1578 unsigned int offset;
1579 size_t total_len = 0; 1579 size_t total_len = 0;
1580 int num_pages;
1580 1581
1581 req = fuse_get_req(fc, FUSE_MAX_PAGES_PER_REQ); 1582 offset = outarg->offset & ~PAGE_CACHE_MASK;
1583 file_size = i_size_read(inode);
1584
1585 num = outarg->size;
1586 if (outarg->offset > file_size)
1587 num = 0;
1588 else if (outarg->offset + num > file_size)
1589 num = file_size - outarg->offset;
1590
1591 num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
1592 num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ);
1593
1594 req = fuse_get_req(fc, num_pages);
1582 if (IS_ERR(req)) 1595 if (IS_ERR(req))
1583 return PTR_ERR(req); 1596 return PTR_ERR(req);
1584 1597
1585 offset = outarg->offset & ~PAGE_CACHE_MASK;
1586
1587 req->in.h.opcode = FUSE_NOTIFY_REPLY; 1598 req->in.h.opcode = FUSE_NOTIFY_REPLY;
1588 req->in.h.nodeid = outarg->nodeid; 1599 req->in.h.nodeid = outarg->nodeid;
1589 req->in.numargs = 2; 1600 req->in.numargs = 2;
@@ -1592,14 +1603,8 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
1592 req->end = fuse_retrieve_end; 1603 req->end = fuse_retrieve_end;
1593 1604
1594 index = outarg->offset >> PAGE_CACHE_SHIFT; 1605 index = outarg->offset >> PAGE_CACHE_SHIFT;
1595 file_size = i_size_read(inode);
1596 num = outarg->size;
1597 if (outarg->offset > file_size)
1598 num = 0;
1599 else if (outarg->offset + num > file_size)
1600 num = file_size - outarg->offset;
1601 1606
1602 while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) { 1607 while (num && req->num_pages < num_pages) {
1603 struct page *page; 1608 struct page *page;
1604 unsigned int this_num; 1609 unsigned int this_num;
1605 1610