]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: handle readdir reply without Fs cap 37232/head
authorYan, Zheng <zyan@redhat.com>
Sun, 16 Aug 2020 03:11:29 +0000 (11:11 +0800)
committerVicente Cheng <freeze.bilsted@gmail.com>
Fri, 18 Sep 2020 11:01:30 +0000 (11:01 +0000)
clear dir complete flag when Fs cap is revoked.

Fixes: https://tracker.ceph.com/issues/42365
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit 535ae64b2dc09044c76f14f70acaf7c3cf870180)

src/client/Client.cc

index f1facc596f34b2b1e89bcf2892b5eba4918308dc..181672e879fe158647e11e9e2cfb264fa8ca63fe 100755 (executable)
@@ -698,7 +698,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
@@ -1008,13 +1007,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);
   }
@@ -1067,6 +1064,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;
@@ -1271,7 +1272,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);
     }
 
@@ -1359,7 +1359,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
        }
@@ -3101,7 +3100,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
     }
@@ -3996,10 +3994,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);
   }