lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 12 Sep 2012 18:24:42 +0200
From:	Miklos Szeredi <miklos@...redi.hu>
To:	Maxim Patlasov <mpatlasov@...allels.com>
Cc:	fuse-devel@...ts.sourceforge.net, linux-kernel@...r.kernel.org,
	devel@...nvz.org
Subject: Re: [PATCH 3/6] fuse: rework fuse_retrieve()

Maxim Patlasov <mpatlasov@...allels.com> writes:

> 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 moslty shuffling lines.
>
> The patch also contains one-line fix suggested by Miklos: the loop iterating
> over pages from inode mapping should interpret 'offset' as offset in the very
> first page only.

That fix is already in -linus, so let's leave it out of this patch.

Thanks,
Miklos

> ---
>  fs/fuse/dev.c |   26 ++++++++++++++++----------
>  1 files changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index 6e38af5..cf69df3 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -1562,13 +1562,24 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
>  	unsigned int num;
>  	unsigned int offset;
>  	size_t total_len = 0;
> +	int num_pages;
>  
> -	req = fuse_get_req_multipage(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_multipage(fc, num_pages);
>  	if (IS_ERR(req))
>  		return PTR_ERR(req);
>  
> -	offset = outarg->offset & ~PAGE_CACHE_MASK;
> -
>  	req->in.h.opcode = FUSE_NOTIFY_REPLY;
>  	req->in.h.nodeid = outarg->nodeid;
>  	req->in.numargs = 2;
> @@ -1577,14 +1588,8 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
>  	req->end = fuse_retrieve_end;
>  
>  	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;
>  		unsigned int this_num;
>  
> @@ -1596,6 +1601,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
>  		req->pages[req->num_pages] = page;
>  		req->num_pages++;
>  
> +		offset = 0;
>  		num -= this_num;
>  		total_len += this_num;
>  		index++;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ