aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authormajianpeng <majianpeng@gmail.com>2013-08-06 04:20:38 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-09 15:24:25 -0500
commit533bc2950e085ee99225655f60276760c00af31f (patch)
tree5ce118050f15063624b69a4bfe362eb20edf50fa /fs/ceph
parent3834fb30d260b8fa6401fff271c65cd29ba94424 (diff)
ceph: fix bugs about handling short-read for sync read mode.
commit 02ae66d8b229708fd94b764f6c17ead1c7741fcf upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/file.c39
1 files changed, 16 insertions, 23 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 5b9baf5a867f..1ac0a59867dc 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -349,44 +349,37 @@ more:
349 dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read, 349 dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read,
350 ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); 350 ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
351 351
352 if (ret > 0) { 352 if (ret >= 0) {
353 int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; 353 int didpages;
354 354 if (was_short && (pos + ret < inode->i_size)) {
355 if (read < pos - off) { 355 u64 tmp = min(this_len - ret,
356 dout(" zero gap %llu to %llu\n", off + read, pos); 356 inode->i_size - pos - ret);
357 ceph_zero_page_vector_range(page_align + read, 357 dout(" zero gap %llu to %llu\n",
358 pos - off - read, pages); 358 pos + ret, pos + ret + tmp);
359 ceph_zero_page_vector_range(page_align + read + ret,
360 tmp, pages);
361 ret += tmp;
359 } 362 }
363
364 didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
360 pos += ret; 365 pos += ret;
361 read = pos - off; 366 read = pos - off;
362 left -= ret; 367 left -= ret;
363 page_pos += didpages; 368 page_pos += didpages;
364 pages_left -= didpages; 369 pages_left -= didpages;
365 370
366 /* hit stripe? */ 371 /* hit stripe and need continue*/
367 if (left && hit_stripe) 372 if (left && hit_stripe && pos < inode->i_size)
368 goto more; 373 goto more;
369 } 374 }
370 375
371 if (was_short) { 376 if (ret >= 0) {
377 ret = read;
372 /* did we bounce off eof? */ 378 /* did we bounce off eof? */
373 if (pos + left > inode->i_size) 379 if (pos + left > inode->i_size)
374 *checkeof = 1; 380 *checkeof = 1;
375
376 /* zero trailing bytes (inside i_size) */
377 if (left > 0 && pos < inode->i_size) {
378 if (pos + left > inode->i_size)
379 left = inode->i_size - pos;
380
381 dout("zero tail %llu\n", left);
382 ceph_zero_page_vector_range(page_align + read, left,
383 pages);
384 read += left;
385 }
386 } 381 }
387 382
388 if (ret >= 0)
389 ret = read;
390 dout("striped_read returns %d\n", ret); 383 dout("striped_read returns %d\n", ret);
391 return ret; 384 return ret;
392} 385}