diff options
-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 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 | } |