]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't revoke/resume stale caps while exporting caps
authorYan, Zheng <zyan@redhat.com>
Fri, 2 Dec 2016 09:39:48 +0000 (17:39 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 8 Dec 2016 00:12:59 +0000 (08:12 +0800)
The revoke/resume cycle increases capability's sequence, which
confuses clients. The caps get removed if exporting succeeds.
We only need to revoke/resume stale caps after exporting fails.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CInode.h
src/mds/Locker.cc
src/mds/Locker.h
src/mds/Migrator.cc

index 3980686235779775a9f07af6849170fc012b9903..ed928ffc48ed9c496a9e6268c19b625a40a7e765 100644 (file)
@@ -218,6 +218,7 @@ public:
   static const int STATE_DIRTYPOOL =   (1<<18);
   static const int STATE_REPAIRSTATS = (1<<19);
   static const int STATE_MISSINGOBJS = (1<<20);
+  static const int STATE_EVALSTALECAPS = (1<<21);
   // orphan inode needs notification of releasing reference
   static const int STATE_ORPHAN =      STATE_NOTIFYREF;
 
index 544975ef3a98479e90c8f5186d2f12dca9d981fc..e4fd8ef5a8eef9937f56cbbfff2ff9c7a065a40b 100644 (file)
@@ -2004,37 +2004,47 @@ void Locker::issue_truncate(CInode *in)
     check_inode_max_size(in);
 }
 
+
+void Locker::revoke_stale_caps(Capability *cap)
+{
+  CInode *in = cap->get_inode();
+  if (in->state_test(CInode::STATE_EXPORTINGCAPS)) {
+    // if export succeeds, the cap will be removed. if export fails, we need to
+    // revoke the cap if it's still stale.
+    in->state_set(CInode::STATE_EVALSTALECAPS);
+    return;
+  }
+
+  int issued = cap->issued();
+  if (issued & ~CEPH_CAP_PIN) {
+    dout(10) << " revoking " << ccap_string(issued) << " on " << *in << dendl;
+    cap->revoke();
+
+    if (in->is_auth() &&
+       in->inode.client_ranges.count(cap->get_client()))
+      in->state_set(CInode::STATE_NEEDSRECOVER);
+
+    if (!in->filelock.is_stable()) eval_gather(&in->filelock);
+    if (!in->linklock.is_stable()) eval_gather(&in->linklock);
+    if (!in->authlock.is_stable()) eval_gather(&in->authlock);
+    if (!in->xattrlock.is_stable()) eval_gather(&in->xattrlock);
+
+    if (in->is_auth()) {
+      try_eval(in, CEPH_CAP_LOCKS);
+    } else {
+      request_inode_file_caps(in);
+    }
+  }
+}
+
 void Locker::revoke_stale_caps(Session *session)
 {
   dout(10) << "revoke_stale_caps for " << session->info.inst.name << dendl;
-  client_t client = session->get_client();
 
   for (xlist<Capability*>::iterator p = session->caps.begin(); !p.end(); ++p) {
     Capability *cap = *p;
     cap->mark_stale();
-    CInode *in = cap->get_inode();
-    int issued = cap->issued();
-    if (issued & ~CEPH_CAP_PIN) {
-      dout(10) << " revoking " << ccap_string(issued) << " on " << *in << dendl;      
-      cap->revoke();
-
-      if (in->is_auth() &&
-         in->inode.client_ranges.count(client))
-       in->state_set(CInode::STATE_NEEDSRECOVER);
-
-      if (!in->filelock.is_stable()) eval_gather(&in->filelock);
-      if (!in->linklock.is_stable()) eval_gather(&in->linklock);
-      if (!in->authlock.is_stable()) eval_gather(&in->authlock);
-      if (!in->xattrlock.is_stable()) eval_gather(&in->xattrlock);
-
-      if (in->is_auth()) {
-       try_eval(in, CEPH_CAP_LOCKS);
-      } else {
-       request_inode_file_caps(in);
-      }
-    } else {
-      dout(10) << " nothing issued on " << *in << dendl;
-    }
+    revoke_stale_caps(cap);
   }
 }
 
@@ -2049,6 +2059,14 @@ void Locker::resume_stale_caps(Session *session)
     if (cap->is_stale()) {
       dout(10) << " clearing stale flag on " << *in << dendl;
       cap->clear_stale();
+
+      if (in->state_test(CInode::STATE_EXPORTINGCAPS)) {
+       // if export succeeds, the cap will be removed. if export fails,
+       // we need to re-issue the cap if it's not stale.
+       in->state_set(CInode::STATE_EVALSTALECAPS);
+       continue;
+      }
+
       if (!in->is_auth() || !eval(in, CEPH_CAP_LOCKS))
        issue_caps(in, cap);
     }
index 5d9bde5803539404a3811ecfe1bcabf1ec172be1..7c3fcd9b277f06cff30feb57ff7e10360ac77083 100644 (file)
@@ -234,13 +234,14 @@ public:
   void mark_updated_Filelock(ScatterLock *lock);
 
   // -- file i/o --
- public:
+public:
   version_t issue_file_data_version(CInode *in);
   Capability* issue_new_caps(CInode *in, int mode, Session *session, SnapRealm *conrealm, bool is_replay);
   bool issue_caps(CInode *in, Capability *only_cap=0);
   void issue_caps_set(set<CInode*>& inset);
   void issue_truncate(CInode *in);
   void revoke_stale_caps(Session *session);
+  void revoke_stale_caps(Capability *cap);
   void resume_stale_caps(Session *session);
   void remove_stale_leases(Session *session);
 
index 1173d3550080ed7eaea9aaf1d0bbe7a175b613cc..8bd3172f4b09b47732d252caf0c5be8468767bc2 100644 (file)
@@ -1637,6 +1637,8 @@ void Migrator::export_reverse(CDir *dir)
 {
   dout(7) << "export_reverse " << *dir << dendl;
 
+  set<CInode*> to_eval;
+
   set<CDir*> bounds;
   cache->get_subtree_bounds(dir, bounds);
 
@@ -1653,6 +1655,10 @@ void Migrator::export_reverse(CDir *dir)
        continue;
       CInode *in = p->second->get_linkage()->get_inode();
       in->abort_export();
+      if (in->state_test(CInode::STATE_EVALSTALECAPS)) {
+       in->state_clear(CInode::STATE_EVALSTALECAPS);
+       to_eval.insert(in);
+      }
       if (in->is_dir())
        in->get_nested_dirfrags(rq);
     }
@@ -1680,6 +1686,22 @@ void Migrator::export_reverse(CDir *dir)
   // unfreeze
   dir->unfreeze_tree();
 
+  // revoke/resume stale caps
+  for (auto in : to_eval) {
+    bool need_issue = false;
+    for (auto& p : in->get_client_caps()) {
+      Capability *cap = p.second;
+      if (cap->is_stale()) {
+       mds->locker->revoke_stale_caps(cap);
+      } else {
+       need_issue = true;
+      }
+    }
+    if (need_issue &&
+       (!in->is_auth() || !mds->locker->eval(in, CEPH_CAP_LOCKS)))
+      mds->locker->issue_caps(in);
+  }
+
   cache->show_cache();
 }