aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/file.c
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2010-02-04 13:41:41 -0800
committerSage Weil <sage@newdream.net>2010-02-11 11:48:49 -0800
commit972f0d3ab1a15cb5d790dd8c53903066084b28f2 (patch)
tree42d47841a5bee10cea81c8e1eb44b6bc4f1f942e /fs/ceph/file.c
parent02f90c61096ec3ad691e808a4aa7ca5a06e550ec (diff)
downloadkernel_samsung_tuna-972f0d3ab1a15cb5d790dd8c53903066084b28f2.zip
kernel_samsung_tuna-972f0d3ab1a15cb5d790dd8c53903066084b28f2.tar.gz
kernel_samsung_tuna-972f0d3ab1a15cb5d790dd8c53903066084b28f2.tar.bz2
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/ceph/file.c')
-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 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;
}