ceph: fix reset_readdir()
authorYan, Zheng <zheng.z.yan@intel.com>
Fri, 28 Feb 2014 08:36:09 +0000 (16:36 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Thu, 3 Apr 2014 02:33:52 +0000 (10:33 +0800)
When changing readdir postion, fi->next_offset should be set to 0
if the new postion is not in the first dirfrag.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Alex Elder <elder@linaro.org>
fs/ceph/dir.c

index a7eaf9692aa6811092ff002e6e87f6e588c34bb2..8ce8833e9c028b028799671a38876c1bfdf381d2 100644 (file)
@@ -454,7 +454,7 @@ more:
        return 0;
 }
 
-static void reset_readdir(struct ceph_file_info *fi)
+static void reset_readdir(struct ceph_file_info *fi, unsigned frag)
 {
        if (fi->last_readdir) {
                ceph_mdsc_put_request(fi->last_readdir);
@@ -462,7 +462,10 @@ static void reset_readdir(struct ceph_file_info *fi)
        }
        kfree(fi->last_name);
        fi->last_name = NULL;
-       fi->next_offset = 2;  /* compensate for . and .. */
+       if (ceph_frag_is_leftmost(frag))
+               fi->next_offset = 2;  /* compensate for . and .. */
+       else
+               fi->next_offset = 0;
        if (fi->dentry) {
                dput(fi->dentry);
                fi->dentry = NULL;
@@ -507,7 +510,7 @@ static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence)
                    fpos_frag(offset) != fi->frag ||
                    fpos_off(offset) < fi->offset) {
                        dout("dir_llseek dropping %p content\n", file);
-                       reset_readdir(fi);
+                       reset_readdir(fi, fpos_frag(offset));
                }
 
                /* bump dir_release_count if we did a forward seek */