Re: [PATCH] ceph: fix bugs about handling short-read for sync read mode.

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

 



On Fri, 2 Aug 2013, majianpeng wrote:
> cephfs . show_layout
> >layyout.data_pool:     0
> >layout.object_size:   4194304
> >layout.stripe_unit:   4194304
> >layout.stripe_count:  1
> 
> TestA:
> >dd if=/dev/urandom of=test bs=1M count=2 oflag=direct
> >dd if=/dev/urandom of=test bs=1M count=2 seek=4  oflag=direct
> >dd if=test of=/dev/null bs=6M count=1 iflag=direct
> The messages from func striped_read are:
> ceph:           file.c:350  : striped_read 0~6291456 (read 0) got 2097152 HITSTRIPE SHORT
> ceph:           file.c:350  : striped_read 2097152~4194304 (read 2097152) got 0 HITSTRIPE SHORT
> ceph:           file.c:381  : zero tail 4194304
> ceph:           file.c:390  : striped_read returns 6291456
> The hole of file is from 2M--4M.But actualy it zero the last 4M include
> the last 2M area which isn't a hole.
> Using this patch, the messages are:
> ceph:           file.c:350  : striped_read 0~6291456 (read 0) got 2097152 HITSTRIPE SHORT
> ceph:           file.c:358  :  zero gap 2097152 to 4194304
> ceph:           file.c:350  : striped_read 4194304~2097152 (read 4194304) got 2097152
> ceph:           file.c:384  : striped_read returns 6291456
> 
> TestB:
> >echo majianpeng > test
> >dd if=test of=/dev/null bs=2M count=1 iflag=direct
> The messages are:
> ceph:           file.c:350  : striped_read 0~6291456 (read 0) got 11 HITSTRIPE SHORT
> ceph:           file.c:350  : striped_read 11~6291445 (read 11) got 0 HITSTRIPE SHORT
> ceph:           file.c:390  : striped_read returns 11
> For this case,it did once more striped_read.It's no meaningless.
> Using this patch, the message are:
> ceph:           file.c:350  : striped_read 0~6291456 (read 0) got 11 HITSTRIPE SHORT
> ceph:           file.c:384  : striped_read returns 11
> 
> Big thanks to Yan Zheng for the patch.

Thanks for working through this!

Do you mind putting the test into a simple .sh script (or whatever) that 
verifies this is working properly (that the read returns the correct data) 
on a file in the currenct directory?  Then we can add this to the 
collection of tests in ceph.git/qa/workunits.  Probably writing the same 
thing to $CWD/test and /tmp/test.$$ and running cmp to verify they match 
is the simplest.

Thanks!
sage



> 
> Signed-off-by: Jianpeng Ma <majianpeng@xxxxxxxxx>
> Reviewed-by: Yan, Zheng <zheng.z.yan@xxxxxxxxx>
> ---
>  fs/ceph/file.c | 40 +++++++++++++++++-----------------------
>  1 file changed, 17 insertions(+), 23 deletions(-)
> 
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index 2ddf061..3d8d14d 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -349,44 +349,38 @@ more:
>  	dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
>  	     ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
>  
> -	if (ret > 0) {
> -		int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
> -
> -		if (read < pos - off) {
> -			dout(" zero gap %llu to %llu\n", off + read, pos);
> -			ceph_zero_page_vector_range(page_align + read,
> -						    pos - off - read, pages);
> +	if (ret >= 0) {
> +		int  didpages;
> +		if (was_short && (pos + ret < inode->i_size)) {
> +			u64 tmp = min(this_len - ret,
> +				 inode->i_size - pos - ret);
> +			dout(" zero gap %llu to %llu\n",
> +				pos + ret, pos + ret + tmp);
> +			ceph_zero_page_vector_range(page_align + read + ret,
> +							tmp, pages);
> +			ret += tmp;
>  		}
> +
> +		didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
>  		pos += ret;
>  		read = pos - off;
>  		left -= ret;
>  		page_pos += didpages;
>  		pages_left -= didpages;
>  
> -		/* hit stripe? */
> -		if (left && hit_stripe)
> +		/* hit stripe and need continue*/
> +		if (left && hit_stripe && pos < inode->i_size)
>  			goto more;
> +
>  	}
>  
> -	if (was_short) {
> +	if (ret >= 0) {
> +		ret = read;
>  		/* did we bounce off eof? */
>  		if (pos + left > inode->i_size)
>  			*checkeof = 1;
> -
> -		/* zero trailing bytes (inside i_size) */
> -		if (left > 0 && pos < inode->i_size) {
> -			if (pos + left > inode->i_size)
> -				left = inode->i_size - pos;
> -
> -			dout("zero tail %d\n", left);
> -			ceph_zero_page_vector_range(page_align + read, left,
> -						    pages);
> -			read += left;
> -		}
>  	}
>  
> -	if (ret >= 0)
> -		ret = read;
>  	dout("striped_read returns %d\n", ret);
>  	return ret;
>  }
> -- 
> 1.8.1.2
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux