From 535ae64b2dc09044c76f14f70acaf7c3cf870180 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Sun, 16 Aug 2020 11:11:29 +0800 Subject: [PATCH] client: handle readdir reply without Fs cap clear dir complete flag when Fs cap is revoked. Fixes: https://tracker.ceph.com/issues/42365 Signed-off-by: "Yan, Zheng" --- src/client/Client.cc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index e7eb2c23ef7..8aece98b253 100755 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -709,7 +709,6 @@ void Client::trim_dentry(Dentry *dn) << dendl; if (dn->inode) { Inode *diri = dn->dir->parent_inode; - diri->dir_release_count++; clear_dir_complete_and_ordered(diri, true); } unlink(dn, false, false); // drop dir, drop dentry @@ -1019,13 +1018,11 @@ Dentry *Client::insert_dentry_inode(Dir *dir, const string& dname, LeaseStat *dl if (old_dentry) { if (old_dentry->dir != dir) { Inode *old_diri = old_dentry->dir->parent_inode; - old_diri->dir_ordered_count++; clear_dir_complete_and_ordered(old_diri, false); } unlink(old_dentry, dir == old_dentry->dir, false); // drop dentry, keep dir open if its the same dir } Inode *diri = dir->parent_inode; - diri->dir_ordered_count++; clear_dir_complete_and_ordered(diri, false); dn = link(dir, dname, in, dn); } @@ -1078,6 +1075,10 @@ void Client::update_dir_dist(Inode *in, DirStat *dst) void Client::clear_dir_complete_and_ordered(Inode *diri, bool complete) { + if (complete) + diri->dir_release_count++; + else + diri->dir_ordered_count++; if (diri->flags & I_COMPLETE) { if (complete) { ldout(cct, 10) << " clearing (I_COMPLETE|I_DIR_ORDERED) on " << *diri << dendl; @@ -1282,7 +1283,6 @@ Inode* Client::insert_trace(MetaRequest *request, MetaSession *session) Dentry *d = request->dentry(); if (d) { Inode *diri = d->dir->parent_inode; - diri->dir_release_count++; clear_dir_complete_and_ordered(diri, true); } @@ -1370,7 +1370,6 @@ Inode* Client::insert_trace(MetaRequest *request, MetaSession *session) if (diri->dir && diri->dir->dentries.count(dname)) { dn = diri->dir->dentries[dname]; if (dn->inode) { - diri->dir_ordered_count++; clear_dir_complete_and_ordered(diri, false); unlink(dn, true, true); // keep dir, dentry } @@ -3134,7 +3133,6 @@ Dentry* Client::link(Dir *dir, const string& name, Inode *in, Dentry *dn) Dentry *olddn = in->get_first_parent(); ceph_assert(olddn->dir != dir || olddn->name != name); Inode *old_diri = olddn->dir->parent_inode; - old_diri->dir_release_count++; clear_dir_complete_and_ordered(old_diri, true); unlink(olddn, true, true); // keep dir, dentry } @@ -4048,10 +4046,10 @@ void Client::check_cap_issue(Inode *in, unsigned issued) !(had & CEPH_CAP_FILE_CACHE)) in->cache_gen++; - if ((issued & CEPH_CAP_FILE_SHARED) && - !(had & CEPH_CAP_FILE_SHARED)) { - in->shared_gen++; - + if ((issued & CEPH_CAP_FILE_SHARED) != + (had & CEPH_CAP_FILE_SHARED)) { + if (issued & CEPH_CAP_FILE_SHARED) + in->shared_gen++; if (in->is_dir()) clear_dir_complete_and_ordered(in, true); }