Re: [RFC PATCH 1/5] ext4: fix reserved cluster accounting at delayed write time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>

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@xxxxxxxx>
SUSE Labs, CR



[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux