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, 30 May 2018 16:08:23 +0200
From:   Jan Kara <jack@...e.cz>
To:     Eric Whitney <enwlinux@...il.com>
Cc:     linux-ext4@...r.kernel.org, tytso@....edu
Subject: Re: [RFC PATCH 1/5] ext4: fix reserved cluster accounting at delayed
 write time

On Sun 13-05-18 13:56:20, Eric Whitney wrote:
> The code in ext4_da_map_blocks sometimes reserves space for more
> delayed allocated clusters than it should, resulting in premature
> ENOSPC, exceeded quota, and inaccurate free space reporting.
> 
> It fails to check the extents status tree for written and unwritten
> clusters which have already been allocated and which share a cluster
> with the block being delayed allocated.  In addition, it fails to
> continue on and search the extent tree when no delayed allocated or
> allocated clusters have been found in the extents status tree.  Written
> extents may be purged from the extents status tree under memory pressure.
> Only delayed and unwritten delayed extents are guaranteed to be retained.
> 
> Signed-off-by: Eric Whitney <enwlinux@...il.com>

Thanks for the patch Eric. Some comments are below.

> diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
> index c969275ce3ee..872782ba8bc3 100644
> --- a/fs/ext4/extents.c
> +++ b/fs/ext4/extents.c
> @@ -3846,6 +3846,47 @@ int ext4_find_delalloc_cluster(struct inode *inode, ext4_lblk_t lblk)
>  	return ext4_find_delalloc_range(inode, lblk_start, lblk_end);
>  }
>  
> +/*
> + * If the block range specified by @start and @end contains an es extent
> + * matched by the matching function specified by @match_fn, return 1.  Else,
> + * return 0.
> + */
> +int ext4_find_range(struct inode *inode,
> +		    int (*match_fn)(struct extent_status *es),
> +		    ext4_lblk_t start,
> +		    ext4_lblk_t end)
> +{
> +	struct extent_status es;
> +
> +	ext4_es_find_extent_range(inode, match_fn, start, end, &es);
> +	if (es.es_len == 0)
> +		return 0; /* there is no matching extent in this tree */
> +	else if (es.es_lblk <= start &&
> +		 start < es.es_lblk + es.es_len)
> +		return 1;
> +	else if (start <= es.es_lblk && es.es_lblk <= end)
> +		return 1;
> +	else
> +		return 0;

No need to elses here. Also how could is possibly happen that es.es_len > 0
and we don't have an extent we want? That would be a bug in
ext4_es_find_extent_range(), wouldn't it?

> diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
> index 763ef185dd17..0c395b5a57a2 100644
> --- a/fs/ext4/extents_status.c
> +++ b/fs/ext4/extents_status.c
> @@ -296,6 +296,70 @@ void ext4_es_find_delayed_extent_range(struct inode *inode,
>  	trace_ext4_es_find_delayed_extent_range_exit(inode, es);
>  }
>  
> +/*
> + * Find the first es extent in the block range specified by @lblk and @end
> + * that satisfies the matching function specified by @match_fn.  If a
> + * match is found, it's returned in @es.  If not, a struct extents_status
> + * is returned in @es whose es_lblk, es_len, and es_pblk components are 0.
> + *
> + * This function is derived from ext4_es_find_delayed_extent_range().
> + * In the future, it could be used to replace it with the use of a suitable
> + * matching function to avoid redundant code.
> + */

Yes, please do that - write a separate patch implementing
ext4_es_find_extent_range() and make ext4_es_find_delayed_extent_range()
use it.

Otherwise the patch looks good to me.

								Honza
-- 
Jan Kara <jack@...e.com>
SUSE Labs, CR

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ