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

Commit 4d53dc99 authored by Maxim Patlasov's avatar Maxim Patlasov Committed by Miklos Szeredi
Browse files

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: default avatarMaxim Patlasov <mpatlasov@parallels.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
parent b111c8c0
Loading
Loading
Loading
Loading
+15 −10
Original line number Original line Diff line number Diff line
@@ -1577,13 +1577,24 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
	unsigned int num;
	unsigned int num;
	unsigned int offset;
	unsigned int offset;
	size_t total_len = 0;
	size_t total_len = 0;
	int num_pages;


	req = fuse_get_req(fc, FUSE_MAX_PAGES_PER_REQ);
	offset = outarg->offset & ~PAGE_CACHE_MASK;
	file_size = i_size_read(inode);

	num = outarg->size;
	if (outarg->offset > file_size)
		num = 0;
	else if (outarg->offset + num > file_size)
		num = file_size - outarg->offset;

	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
	num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ);

	req = fuse_get_req(fc, num_pages);
	if (IS_ERR(req))
	if (IS_ERR(req))
		return PTR_ERR(req);
		return PTR_ERR(req);


	offset = outarg->offset & ~PAGE_CACHE_MASK;

	req->in.h.opcode = FUSE_NOTIFY_REPLY;
	req->in.h.opcode = FUSE_NOTIFY_REPLY;
	req->in.h.nodeid = outarg->nodeid;
	req->in.h.nodeid = outarg->nodeid;
	req->in.numargs = 2;
	req->in.numargs = 2;
@@ -1592,14 +1603,8 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
	req->end = fuse_retrieve_end;
	req->end = fuse_retrieve_end;


	index = outarg->offset >> PAGE_CACHE_SHIFT;
	index = outarg->offset >> PAGE_CACHE_SHIFT;
	file_size = i_size_read(inode);
	num = outarg->size;
	if (outarg->offset > file_size)
		num = 0;
	else if (outarg->offset + num > file_size)
		num = file_size - outarg->offset;


	while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) {
	while (num && req->num_pages < num_pages) {
		struct page *page;
		struct page *page;
		unsigned int this_num;
		unsigned int this_num;