diff options
author | Yehuda Sadeh <yehuda@hq.newdream.net> | 2010-02-04 13:41:41 -0800 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-02-11 11:48:49 -0800 |
commit | 972f0d3ab1a15cb5d790dd8c53903066084b28f2 (patch) | |
tree | 42d47841a5bee10cea81c8e1eb44b6bc4f1f942e /fs | |
parent | 02f90c61096ec3ad691e808a4aa7ca5a06e550ec (diff) | |
download | op-kernel-dev-972f0d3ab1a15cb5d790dd8c53903066084b28f2.zip op-kernel-dev-972f0d3ab1a15cb5d790dd8c53903066084b28f2.tar.gz |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/file.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 2d88c80..43bd2f2 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) { int i = off >> PAGE_CACHE_SHIFT; + off &= ~PAGE_CACHE_MASK; + dout("zero_page_vector_page %u~%u\n", off, len); - BUG_ON(len < PAGE_CACHE_SIZE); /* leading partial page? */ - if (off & ~PAGE_CACHE_MASK) { + if (off) { + int end = min((int)PAGE_CACHE_SIZE, off + len); dout("zeroing %d %p head from %d\n", i, pages[i], - (int)(off & ~PAGE_CACHE_MASK)); - zero_user_segment(pages[i], off & ~PAGE_CACHE_MASK, - PAGE_CACHE_SIZE); - off += PAGE_CACHE_SIZE; - off &= PAGE_CACHE_MASK; + (int)off); + zero_user_segment(pages[i], off, end); + len -= (end - off); i++; } while (len >= PAGE_CACHE_SIZE) { dout("zeroing %d %p\n", i, pages[i]); zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); - off += PAGE_CACHE_SIZE; len -= PAGE_CACHE_SIZE; i++; } @@ -437,7 +436,7 @@ static int striped_read(struct inode *inode, struct ceph_client *client = ceph_inode_to_client(inode); struct ceph_inode_info *ci = ceph_inode(inode); u64 pos, this_len; - int page_off = off & ~PAGE_CACHE_SIZE; /* first byte's offset in page */ + int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */ int left, pages_left; int read; struct page **page_pos; @@ -493,6 +492,7 @@ more: dout("zero tail\n"); zero_page_vector_range(page_off + read, len - read, pages); + read = len; goto out; } |