diff options
author | Yan, Zheng <zyan@redhat.com> | 2016-10-12 14:48:28 +0800 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2016-10-18 12:09:58 +0200 |
commit | f72f94555aa32b2c4374dde5ad9b960cc4ff32e2 (patch) | |
tree | ea39f8a0ae76f31f4f8004fd7045824ae608e5bb /fs/ceph/inode.c | |
parent | 0d7718f666be181fda1ba2d08f137d87c1419347 (diff) |
ceph: fix readdir vs fragmentation race
following sequence of events tigger the race
- client readdir frag 0* -> got item 'A'
- MDS merges frag 0* and frag 1*
- client send readdir request (frag 1*, offset 2, readdir_start 'A')
- MDS reply items (that are after item 'A') in frag *
Link: http://tracker.ceph.com/issues/17286
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r-- | fs/ceph/inode.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index bca1b49c1c4b..ef4d04647325 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1511,7 +1511,8 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, ceph_fill_dirfrag(d_inode(parent), rinfo->dir_dir); } - if (ceph_frag_is_leftmost(frag) && req->r_readdir_offset == 2) { + if (ceph_frag_is_leftmost(frag) && req->r_readdir_offset == 2 && + !(rinfo->hash_order && req->r_path2)) { /* note dir version at start of readdir so we can tell * if any dentries get dropped */ req->r_dir_release_cnt = atomic64_read(&ci->i_release_count); |