diff options
author | majianpeng <majianpeng@gmail.com> | 2013-08-06 04:20:38 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-08-27 15:28:45 -0400 |
commit | 02ae66d8b229708fd94b764f6c17ead1c7741fcf (patch) | |
tree | 3cbb18d37ceb0eb74d8fac86f8da9fd0ef8199f1 /fs/ceph/file.c | |
parent | e90757432361bb8b3ad3c3fd866324ed47875693 (diff) |
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: Yan, Zheng <zheng.z.yan@intel.com>
Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 39 |
1 files changed, 16 insertions, 23 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index d5e12f580671..98b9035b2e81 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -350,44 +350,37 @@ more: | |||
350 | dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read, | 350 | dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read, |
351 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); | 351 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); |
352 | 352 | ||
353 | if (ret > 0) { | 353 | if (ret >= 0) { |
354 | int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; | 354 | int didpages; |
355 | 355 | if (was_short && (pos + ret < inode->i_size)) { | |
356 | if (read < pos - off) { | 356 | u64 tmp = min(this_len - ret, |
357 | dout(" zero gap %llu to %llu\n", off + read, pos); | 357 | inode->i_size - pos - ret); |
358 | ceph_zero_page_vector_range(page_align + read, | 358 | dout(" zero gap %llu to %llu\n", |
359 | pos - off - read, pages); | 359 | pos + ret, pos + ret + tmp); |
360 | ceph_zero_page_vector_range(page_align + read + ret, | ||
361 | tmp, pages); | ||
362 | ret += tmp; | ||
360 | } | 363 | } |
364 | |||
365 | didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; | ||
361 | pos += ret; | 366 | pos += ret; |
362 | read = pos - off; | 367 | read = pos - off; |
363 | left -= ret; | 368 | left -= ret; |
364 | page_pos += didpages; | 369 | page_pos += didpages; |
365 | pages_left -= didpages; | 370 | pages_left -= didpages; |
366 | 371 | ||
367 | /* hit stripe? */ | 372 | /* hit stripe and need continue*/ |
368 | if (left && hit_stripe) | 373 | if (left && hit_stripe && pos < inode->i_size) |
369 | goto more; | 374 | goto more; |
370 | } | 375 | } |
371 | 376 | ||
372 | if (was_short) { | 377 | if (ret >= 0) { |
378 | ret = read; | ||
373 | /* did we bounce off eof? */ | 379 | /* did we bounce off eof? */ |
374 | if (pos + left > inode->i_size) | 380 | if (pos + left > inode->i_size) |
375 | *checkeof = 1; | 381 | *checkeof = 1; |
376 | |||
377 | /* zero trailing bytes (inside i_size) */ | ||
378 | if (left > 0 && pos < inode->i_size) { | ||
379 | if (pos + left > inode->i_size) | ||
380 | left = inode->i_size - pos; | ||
381 | |||
382 | dout("zero tail %llu\n", left); | ||
383 | ceph_zero_page_vector_range(page_align + read, left, | ||
384 | pages); | ||
385 | read += left; | ||
386 | } | ||
387 | } | 382 | } |
388 | 383 | ||
389 | if (ret >= 0) | ||
390 | ret = read; | ||
391 | dout("striped_read returns %d\n", ret); | 384 | dout("striped_read returns %d\n", ret); |
392 | return ret; | 385 | return ret; |
393 | } | 386 | } |