]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't kill request that has started slave operations
authorYan, Zheng <zyan@redhat.com>
Tue, 6 Dec 2016 01:54:34 +0000 (09:54 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 8 Dec 2016 00:12:59 +0000 (08:12 +0800)
Rollback slave operations is tricky. Make MDcache::request_kill
ignores request that has started slave operations.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/MDCache.cc
src/mds/Server.cc
src/mds/Server.h
src/messages/MMDSSlaveRequest.h

index e30bd9af5c4147e2da9de9cd506a0db439aab5e1..5b24edbdcb15f519e29960adba5e554d7480ab33 100644 (file)
@@ -3398,7 +3398,7 @@ void MDCache::handle_resolve_ack(MMDSResolveAck *ack)
       MDRequestRef mdr = request_get(*p);
       mdr->aborted = true;
       if (mdr->slave_request) {
-       if (mdr->more()->slave_commit) // journaling slave prepare ?
+       if (mdr->slave_did_prepare()) // journaling slave prepare ?
          add_rollback(*p, from);
       } else {
        request_finish(mdr);
@@ -8998,10 +8998,6 @@ void MDCache::request_forward(MDRequestRef& mdr, mds_rank_t who, int port)
 
 void MDCache::dispatch_request(MDRequestRef& mdr)
 {
-  if (mdr->killed) {
-    dout(10) << "request " << *mdr << " was killed" << dendl;
-    return;
-  }
   if (mdr->client_request) {
     mds->server->dispatch_client_request(mdr);
   } else if (mdr->slave_request) {
@@ -9046,10 +9042,13 @@ void MDCache::request_drop_foreign_locks(MDRequestRef& mdr)
     MMDSSlaveRequest *r = new MMDSSlaveRequest(mdr->reqid, mdr->attempt,
                                               MMDSSlaveRequest::OP_FINISH);
 
-    // information about rename imported caps
-    if (mdr->more()->srcdn_auth_mds == *p &&
-       mdr->more()->inode_import.length() > 0)
+    if (mdr->killed && !mdr->committing) {
+      r->mark_abort();
+    } else if (mdr->more()->srcdn_auth_mds == *p &&
+              mdr->more()->inode_import.length() > 0) {
+      // information about rename imported caps
       r->inode_export.claim(mdr->more()->inode_import);
+    }
 
     mds->send_message_mds(r, *p);
   }
@@ -9138,13 +9137,27 @@ void MDCache::request_cleanup(MDRequestRef& mdr)
 
 void MDCache::request_kill(MDRequestRef& mdr)
 {
+  // rollback slave requests is tricky. just let the request proceed.
+  if (mdr->done_locking && mdr->has_more() &&
+      (!mdr->more()->witnessed.empty() || !mdr->more()->waiting_on_slave.empty())) {
+    dout(10) << "request_kill " << *mdr << " -- already started slave requests, no-op" << dendl;
+
+    assert(mdr->used_prealloc_ino == 0);
+    assert(mdr->prealloc_inos.empty());
+
+    mdr->session = NULL;
+    mdr->item_session_request.remove_myself();
+    return;
+  }
+
   mdr->killed = true;
   mdr->mark_event("killing request");
-  if (!mdr->committing) {
+
+  if (mdr->committing) {
+    dout(10) << "request_kill " << *mdr << " -- already committing, no-op" << dendl;
+  } else {
     dout(10) << "request_kill " << *mdr << dendl;
     request_cleanup(mdr);
-  } else {
-    dout(10) << "request_kill " << *mdr << " -- already committing, no-op" << dendl;
   }
 }
 
index af7c513718a3bb8cbb6e984b4f2ad4587b5df1b3..40ae3b66dcfad35c21602ba46afcb755ac813bf8 100644 (file)
@@ -1119,6 +1119,8 @@ void Server::reply_client_request(MDRequestRef& mdr, MClientReply *reply)
 
   mdr->mark_event("replying");
 
+  Session *session = mdr->session;
+
   // note successful request in session map?
   //
   // setfilelock requests are special, they only modify states in MDS memory.
@@ -1126,16 +1128,16 @@ void Server::reply_client_request(MDRequestRef& mdr, MClientReply *reply)
   // setfilelock request, it means that client did not receive corresponding
   // setfilelock reply.  So MDS should re-execute the setfilelock request.
   if (req->may_write() && req->get_op() != CEPH_MDS_OP_SETFILELOCK &&
-      reply->get_result() == 0 && mdr->session) {
+      reply->get_result() == 0 && session) {
     inodeno_t created = mdr->alloc_ino ? mdr->alloc_ino : mdr->used_prealloc_ino;
-    mdr->session->add_completed_request(mdr->reqid.tid, created);
+    session->add_completed_request(mdr->reqid.tid, created);
     if (mdr->ls) {
-      mdr->ls->touched_sessions.insert(mdr->session->info.inst.name);
+      mdr->ls->touched_sessions.insert(session->info.inst.name);
     }
   }
 
   // give any preallocated inos to the session
-  apply_allocated_inos(mdr);
+  apply_allocated_inos(mdr, session);
 
   // get tracei/tracedn from mdr?
   snapid_t snapid = mdr->snapid;
@@ -1144,7 +1146,6 @@ void Server::reply_client_request(MDRequestRef& mdr, MClientReply *reply)
 
   bool is_replay = mdr->client_request->is_replay();
   bool did_early_reply = mdr->did_early_reply;
-  Session *session = mdr->session;
   entity_inst_t client_inst = req->get_source_inst();
   int dentry_wanted = req->get_dentry_wanted();
 
@@ -1161,14 +1162,11 @@ void Server::reply_client_request(MDRequestRef& mdr, MClientReply *reply)
       mdr->cap_releases.erase(tracedn->get_dir()->get_inode()->vino());
   }
 
-  // note client connection to direct my reply
-  ConnectionRef client_con = req->get_connection();
-
   // drop non-rdlocks before replying, so that we can issue leases
   mdcache->request_drop_non_rdlocks(mdr);
 
   // reply at all?
-  if (client_inst.name.is_mds()) {
+  if (client_inst.name.is_mds() || !session) {
     reply->put();   // mds doesn't need a reply
     reply = 0;
   } else {
@@ -1191,7 +1189,7 @@ void Server::reply_client_request(MDRequestRef& mdr, MClientReply *reply)
     reply->set_extra_bl(mdr->reply_extra_bl);
 
     reply->set_mdsmap_epoch(mds->mdsmap->get_epoch());
-    client_con->send_message(reply);
+    req->get_connection()->send_message(reply);
   }
 
   const bool completed = mdr->has_completed;
@@ -1469,15 +1467,20 @@ void Server::handle_osd_map()
 
 void Server::dispatch_client_request(MDRequestRef& mdr)
 {
+  // we shouldn't be waiting on anyone.
+  assert(!mdr->has_more() || mdr->more()->waiting_on_slave.empty());
+
+  if (mdr->killed) {
+    dout(10) << "request " << *mdr << " was killed" << dendl;
+    return;
+  }
+
   MClientRequest *req = mdr->client_request;
 
   if (logger) logger->inc(l_mdss_dispatch_client_request);
 
   dout(7) << "dispatch_client_request " << *req << dendl;
 
-  // we shouldn't be waiting on anyone.
-  assert(!mdr->has_more() || mdr->more()->waiting_on_slave.empty());
-
   if (req->may_write()) {
     if (mdcache->is_readonly()) {
       dout(10) << " read-only FS" << dendl;
@@ -1677,6 +1680,17 @@ void Server::handle_slave_request(MMDSSlaveRequest *m)
       m->put();
       return;
     }
+
+    if (m->get_op() == MMDSSlaveRequest::OP_FINISH && m->is_abort()) {
+      mdr->aborted = true;
+      if (mdr->slave_request) {
+       // only abort on-going xlock, wrlock and auth pin
+       assert(!mdr->slave_did_prepare());
+      } else {
+       mdcache->request_finish(mdr);
+      }
+      return;
+    }
   }
   if (!mdr.get()) {
     // new?
@@ -2395,9 +2409,8 @@ void Server::journal_allocated_inos(MDRequestRef& mdr, EMetaBlob *blob)
                      mds->inotable->get_projected_version());
 }
 
-void Server::apply_allocated_inos(MDRequestRef& mdr)
+void Server::apply_allocated_inos(MDRequestRef& mdr, Session *session)
 {
-  Session *session = mdr->session;
   dout(10) << "apply_allocated_inos " << mdr->alloc_ino
           << " / " << mdr->prealloc_inos
           << " / " << mdr->used_prealloc_ino << dendl;
index d580f1f3bae4ffad51d2f04570edf9dfb23806f5..0669d440db66d2b017846b86c792d3ef0a7710ec 100644 (file)
@@ -145,7 +145,7 @@ public:
   CInode* prepare_new_inode(MDRequestRef& mdr, CDir *dir, inodeno_t useino, unsigned mode,
                            file_layout_t *layout=NULL);
   void journal_allocated_inos(MDRequestRef& mdr, EMetaBlob *blob);
-  void apply_allocated_inos(MDRequestRef& mdr);
+  void apply_allocated_inos(MDRequestRef& mdr, Session *session);
 
   CInode* rdlock_path_pin_ref(MDRequestRef& mdr, int n, set<SimpleLock*>& rdlocks, bool want_auth,
                              bool no_want_auth=false,
index 201ff28abc4a6149fb33596ef8fb2aa3b0d2dd58..2406d75447093641448bcc1a814c4a5d0900cbbb 100644 (file)
@@ -96,10 +96,11 @@ class MMDSSlaveRequest : public Message {
   __s16 op;
   __u16 flags;
 
-  static const unsigned FLAG_NONBLOCK  = 1;
-  static const unsigned FLAG_WOULDBLOCK        = 2;
-  static const unsigned FLAG_NOTJOURNALED = 4;
-  static const unsigned FLAG_EROFS = 8;
+  static const unsigned FLAG_NONBLOCK  =       1<<0;
+  static const unsigned FLAG_WOULDBLOCK        =       1<<1;
+  static const unsigned FLAG_NOTJOURNALED =    1<<2;
+  static const unsigned FLAG_EROFS =           1<<3;
+  static const unsigned FLAG_ABORT =           1<<4;
 
   // for locking
   __u16 lock_type;  // lock object type
@@ -139,6 +140,8 @@ public:
   bool is_not_journaled() { return (flags & FLAG_NOTJOURNALED); }
   void mark_error_rofs() { flags |= FLAG_EROFS; }
   bool is_error_rofs() { return (flags & FLAG_EROFS); }
+  bool is_abort() { return (flags & FLAG_ABORT); }
+  void mark_abort() { flags |= FLAG_ABORT; }
 
   void set_lock_type(int t) { lock_type = t; }