diff mbox

Re: question about striped_read

Message ID 201307310933358798964@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

majianpeng July 31, 2013, 1:36 a.m. UTC
[snip]
I think this patch can do work:
Those case which i tested
A: filesize=0,  buffer=1M
B:  data[2M] | hole| data[2M], bs= 6M/7M
C: data[4m] | hole | hole |data[2M]  bs=16M/18M

Are there some case ignore?
Thanks!
Jianpeng Ma
diff mbox

Patch

diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 2ddf061..96ce893 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -319,7 +319,7 @@  static int striped_read(struct inode *inode,
        int read;
        struct page **page_pos;
        int ret;
-       bool hit_stripe, was_short;
+       bool hit_stripe, was_short, hit_hole = false;
 
        /*
         * we may need to do multiple reads.  not atomic, unfortunately.
@@ -342,21 +342,30 @@  more:
                                  ci->i_truncate_seq,
                                  ci->i_truncate_size,
                                  page_pos, pages_left, page_align);
-       if (ret == -ENOENT)
+
+       if ((ret == 0  || ret == -ENOENT) && pos < inode->i_size)
+               hit_hole = true;
+       else if (ret == -ENOENT)
                ret = 0;
+       
        hit_stripe = this_len < left;
-       was_short = ret >= 0 && ret < this_len;
-       dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
-            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
-
-       if (ret > 0) {
-               int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
-
-               if (read < pos - off) {
-                       dout(" zero gap %llu to %llu\n", off + read, pos);
-                       ceph_zero_page_vector_range(page_align + read,
-                                                   pos - off - read, pages);
+       was_short = ret > 0 && ret < this_len;
+       dout("striped_read %llu~%u (read %u) got %d%s%s%s\n", pos, left, read,
+            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "",
+            hit_hole ? " HITHOLE" : "");
+
+       if (ret > 0 || hit_hole) {
+               int didpages;
+               
+               if (hit_hole) {
+                       ret = this_len; 
+                       dout(" zero hole %llu to %llu\n", pos , pos + ret);
+                       ceph_zero_page_vector_range(page_align + read, 
+                                                       ret, pages);
+                       hit_hole = false;
                }
+               didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
+
                pos += ret;
                read = pos - off;
                left -= ret;