Re: [PATCH 3/3] rewrite __generic_block_fiemap()

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

 



> On Jan 10, 2016, at 11:30 PM, Fan Li <fanofcode.li@xxxxxxxxxxx> wrote:
> 
> There are a few redundant branches in this function and
> if there are more than two blocks of holes after the last
> extent of file, it would fail to add FIEMAP_EXTENT_LAST
> to the last extent.
> Simplify the codes in this patch.
> 
> 
> Signed-off-by: Fan Li <fanofcode.li@xxxxxxxxxxx>
> ---
> fs/ioctl.c |   93 +++++++++++-------------------------------------------------
> 1 file changed, 17 insertions(+), 76 deletions(-)
> 
> diff --git a/fs/ioctl.c b/fs/ioctl.c
> index 5d54377..8e2b426 100644
> --- a/fs/ioctl.c
> +++ b/fs/ioctl.c
> @@ -256,7 +256,6 @@ int __generic_block_fiemap(struct inode *inode,
> 	loff_t isize = i_size_read(inode);
> 	u64 logical = 0, phys = 0, size = 0;
> 	u32 flags = FIEMAP_EXTENT_MERGED;
> -	bool past_eof = false, whole_file = false;
> 	int ret = 0;
> 
> 	ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
> @@ -271,10 +270,8 @@ int __generic_block_fiemap(struct inode *inode,
> 	if (start >= isize)
> 		return 0;
> 
> -	if (start + len > isize) {
> -		whole_file = true;
> +	if (start + len > isize)
> 		len = isize - start;
> -	}
> 
> 	start_blk = logical_to_blk(inode, start);
> 	last_blk = logical_to_blk(inode, start + len - 1);
> @@ -300,91 +297,35 @@ int __generic_block_fiemap(struct inode *inode,
> 		if (!buffer_mapped(&map_bh)) {
> 			start_blk++;
> 
> -			/*
> -			 * We want to handle the case where there is an
> -			 * allocated block at the front of the file, and then
> -			 * nothing but holes up to the end of the file properly,
> -			 * to make sure that extent at the front gets properly
> -			 * marked with FIEMAP_EXTENT_LAST
> -			 */
> -			if (!past_eof &&
> -			    blk_to_logical(inode, start_blk) >= isize)
> -				past_eof = 1;
> -
> +			/* Skip holes unless it indicates the EOF */
> +			if (blk_to_logical(inode, start_blk) < isize)
> +				goto next;
> 			/*
> 			 * First hole after going past the EOF, this is our
> 			 * last extent
> 			 */
> -			if (past_eof && size) {
> -				flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
> -				ret = fiemap_fill_next_extent(fieinfo, logical,
> -							      phys, size,
> -							      flags);
> -			} else if (size) {
> -				ret = fiemap_fill_next_extent(fieinfo, logical,
> -							      phys, size, flags);
> -				size = 0;
> -			}
> -
> -			/* if we have holes up to/past EOF then we're done */
> -			if (start_blk > last_blk || past_eof || ret)
> -				break;
> -		} else {
> -			/*
> -			 * We have gone over the length of what we wanted to
> -			 * map, and it wasn't the entire file, so add the extent
> -			 * we got last time and exit.
> -			 *
> -			 * This is for the case where say we want to map all the
> -			 * way up to the second to the last block in a file, but
> -			 * the last block is a hole, making the second to last
> -			 * block FIEMAP_EXTENT_LAST.  In this case we want to
> -			 * see if there is a hole after the second to last block
> -			 * so we can mark it properly.  If we found data after
> -			 * we exceeded the length we were requesting, then we
> -			 * are good to go, just add the extent to the fieinfo
> -			 * and break
> -			 */
> -			if (start_blk > last_blk && !whole_file) {
> -				ret = fiemap_fill_next_extent(fieinfo, logical,
> -							      phys, size,
> -							      flags);
> -				break;
> -			}
> +			flags |= FIEMAP_EXTENT_LAST;
> +		}
> 
> -			/*
> -			 * if size != 0 then we know we already have an extent
> -			 * to add, so add it.
> -			 */

Why remove this comment?  This is still true.

> -			if (size) {
> -				ret = fiemap_fill_next_extent(fieinfo, logical,
> -							      phys, size,
> -							      flags);
> -				if (ret)
> -					break;
> -			}
> +		if (size)
> +			ret = fiemap_fill_next_extent(fieinfo, logical,
> +					phys, size, flags);

This should align after '(' from the previous line.

> -			logical = blk_to_logical(inode, start_blk);
> -			phys = blk_to_logical(inode, map_bh.b_blocknr);
> -			size = map_bh.b_size;
> -			flags = FIEMAP_EXTENT_MERGED;
> +		if (start_blk > last_blk || ret)
> +			break;
> 
> -			start_blk += logical_to_blk(inode, size);

It would be good to add a comment to this next chunk of code like:

		/* reset values for the next extent */
> +		logical = blk_to_logical(inode, start_blk);
> +		phys = blk_to_logical(inode, map_bh.b_blocknr);
> +		size = map_bh.b_size;
> +		flags = FIEMAP_EXTENT_MERGED;

> 
> -			/*
> -			 * If we are past the EOF, then we need to make sure as
> -			 * soon as we find a hole that the last extent we found
> -			 * is marked with FIEMAP_EXTENT_LAST
> -			 */
> -			if (!past_eof && logical + size >= isize)
> -				past_eof = true;
> -		}
> +		start_blk += logical_to_blk(inode, size);
> +next:
> 		cond_resched();
> 		if (fatal_signal_pending(current)) {
> 			ret = -EINTR;
> 			break;
> 		}
> -
> 	} while (1);
> 
> 	/* If ret is 1 then we just hit the end of the extent array */

What kind of testing have you done with this patch?  I believe there are
some FIEMAP tests in xfstests, though it might make sense to add another
one to cover the case that this patch is fixing.

Cheers, Andreas





Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux