Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02ae66d8 authored by majianpeng's avatar majianpeng Committed by Sage Weil
Browse files

ceph: fix bugs about handling short-read for sync read mode.



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.

Reviewed-by: default avatarYan, Zheng <zheng.z.yan@intel.com>
Signed-off-by: default avatarJianpeng Ma <majianpeng@gmail.com>
parent e9075743
Loading
Loading
Loading
Loading
+16 −23
Original line number Diff line number Diff line
@@ -350,44 +350,37 @@ static int striped_read(struct inode *inode,
	dout("striped_read %llu~%llu (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 %llu\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;
}