aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2010-02-04 16:41:41 -0500
committerSage Weil <sage@newdream.net>2010-02-11 14:48:49 -0500
commit972f0d3ab1a15cb5d790dd8c53903066084b28f2 (patch)
tree42d47841a5bee10cea81c8e1eb44b6bc4f1f942e
parent02f90c61096ec3ad691e808a4aa7ca5a06e550ec (diff)
ceph: fix short synchronous reads
Zeroing of holes was not done correctly: page_off was miscalculated and zeroing the tail didn't not adjust the 'read' value to include the zeroed portion. Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net> Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--fs/ceph/file.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 2d88c805a56c..43bd2f2e51a5 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -395,23 +395,22 @@ static void zero_page_vector_range(int off, int len, struct page **pages)
395{ 395{
396 int i = off >> PAGE_CACHE_SHIFT; 396 int i = off >> PAGE_CACHE_SHIFT;
397 397
398 off &= ~PAGE_CACHE_MASK;
399
398 dout("zero_page_vector_page %u~%u\n", off, len); 400 dout("zero_page_vector_page %u~%u\n", off, len);
399 BUG_ON(len < PAGE_CACHE_SIZE);
400 401
401 /* leading partial page? */ 402 /* leading partial page? */
402 if (off & ~PAGE_CACHE_MASK) { 403 if (off) {
404 int end = min((int)PAGE_CACHE_SIZE, off + len);
403 dout("zeroing %d %p head from %d\n", i, pages[i], 405 dout("zeroing %d %p head from %d\n", i, pages[i],
404 (int)(off & ~PAGE_CACHE_MASK)); 406 (int)off);
405 zero_user_segment(pages[i], off & ~PAGE_CACHE_MASK, 407 zero_user_segment(pages[i], off, end);
406 PAGE_CACHE_SIZE); 408 len -= (end - off);
407 off += PAGE_CACHE_SIZE;
408 off &= PAGE_CACHE_MASK;
409 i++; 409 i++;
410 } 410 }
411 while (len >= PAGE_CACHE_SIZE) { 411 while (len >= PAGE_CACHE_SIZE) {
412 dout("zeroing %d %p\n", i, pages[i]); 412 dout("zeroing %d %p\n", i, pages[i]);
413 zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); 413 zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
414 off += PAGE_CACHE_SIZE;
415 len -= PAGE_CACHE_SIZE; 414 len -= PAGE_CACHE_SIZE;
416 i++; 415 i++;
417 } 416 }
@@ -437,7 +436,7 @@ static int striped_read(struct inode *inode,
437 struct ceph_client *client = ceph_inode_to_client(inode); 436 struct ceph_client *client = ceph_inode_to_client(inode);
438 struct ceph_inode_info *ci = ceph_inode(inode); 437 struct ceph_inode_info *ci = ceph_inode(inode);
439 u64 pos, this_len; 438 u64 pos, this_len;
440 int page_off = off & ~PAGE_CACHE_SIZE; /* first byte's offset in page */ 439 int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */
441 int left, pages_left; 440 int left, pages_left;
442 int read; 441 int read;
443 struct page **page_pos; 442 struct page **page_pos;
@@ -493,6 +492,7 @@ more:
493 dout("zero tail\n"); 492 dout("zero tail\n");
494 zero_page_vector_range(page_off + read, len - read, 493 zero_page_vector_range(page_off + read, len - read,
495 pages); 494 pages);
495 read = len;
496 goto out; 496 goto out;
497 } 497 }
498 498