]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: properly drop imported xlocks.
authorGreg Farnum <gregory.farnum@dreamhost.com>
Thu, 31 Mar 2011 00:10:05 +0000 (17:10 -0700)
committerSage Weil <sage@newdream.net>
Mon, 18 Apr 2011 17:40:04 +0000 (10:40 -0700)
Because we can do an inode import during a rename that skips the usual
channels, we were getting into an odd state with the xlocks (which
were formerly remote and are now local). Clean up the record of
those remote xlocks.

Signed-off-by: Greg Farnum <gregory.farnum@dreamhost.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/Server.cc

index 5609a809c6741fd2f98f619e34eac65ad0232f65..f832a5ffeb36c91f1a1523547dc83579a8e9536f 100644 (file)
@@ -7288,40 +7288,48 @@ void MDCache::dispatch_request(MDRequest *mdr)
 }
 
 
-void MDCache::request_forget_foreign_locks(MDRequest *mdr)
+void MDCache::request_drop_foreign_locks(MDRequest *mdr)
 {
-  // xlocks
+  // clean up slaves
+  //  (will implicitly drop remote dn pins)
+  for (set<int>::iterator p = mdr->more()->slaves.begin();
+       p != mdr->more()->slaves.end();
+       ++p) {
+    MMDSSlaveRequest *r = new MMDSSlaveRequest(mdr->reqid, MMDSSlaveRequest::OP_FINISH);
+    mds->send_message_mds(r, *p);
+  }
+
+  /* strip foreign xlocks out of lock lists, since the OP_FINISH drops them
+   * implicitly. Note that we don't call the finishers -- there shouldn't
+   * be any on a remote lock and the request finish wakes up all
+   * the waiters anyway! */
   set<SimpleLock*>::iterator p = mdr->xlocks.begin();
   while (p != mdr->xlocks.end()) {
     if ((*p)->get_parent()->is_auth()) 
       p++;
     else {
-      dout(10) << "request_forget_foreign_locks " << **p
+      dout(10) << "request_drop_foreign_locks forgetting lock " << **p
               << " on " << *(*p)->get_parent() << dendl;
       (*p)->put_xlock();
       mdr->locks.erase(*p);
       mdr->xlocks.erase(p++);
     }
   }
+
+  mdr->more()->slaves.clear(); /* we no longer have requests out to them, and
+                                * leaving them in can cause double-notifies as
+                                * this function can get called more than once */
 }
 
+void MDCache::request_drop_non_rdlocks(MDRequest *mdr)
+{
+  request_drop_foreign_locks(mdr);
+  mds->locker->drop_non_rdlocks(mdr);
+}
 
 void MDCache::request_drop_locks(MDRequest *mdr)
 {
-  // clean up slaves
-  //  (will implicitly drop remote dn pins)
-  for (set<int>::iterator p = mdr->more()->slaves.begin();
-       p != mdr->more()->slaves.end();
-       ++p) {
-    MMDSSlaveRequest *r = new MMDSSlaveRequest(mdr->reqid, MMDSSlaveRequest::OP_FINISH);
-    mds->send_message_mds(r, *p);
-  }
-
-  // strip foreign xlocks out of lock lists, since the OP_FINISH drops them implicitly.
-  request_forget_foreign_locks(mdr);
-
-
-  // drop locks
+  request_drop_foreign_locks(mdr);
   mds->locker->drop_locks(mdr);
 }
 
index 4a0f28370642f208a20ff74fc163c8a07af9b780..17fc9faee85e63f9b8a39157e7a826b5a4a98654 100644 (file)
@@ -597,7 +597,8 @@ public:
   void request_finish(MDRequest *mdr);
   void request_forward(MDRequest *mdr, int mds, int port=0);
   void dispatch_request(MDRequest *mdr);
-  void request_forget_foreign_locks(MDRequest *mdr);
+  void request_drop_foreign_locks(MDRequest *mdr);
+  void request_drop_non_rdlocks(MDRequest *r);
   void request_drop_locks(MDRequest *r);
   void request_cleanup(MDRequest *r);
   
index e1307a89d7c062a7163dc6f24887b5dc64bcbc83..2c3e3795c220c8e3a3e0b7d37c17fd6b0c74670a 100644 (file)
@@ -887,7 +887,7 @@ void Server::reply_request(MDRequest *mdr, MClientReply *reply, CInode *tracei,
   client_con->get();
 
   // drop non-rdlocks before replying, so that we can issue leases
-  mds->locker->drop_non_rdlocks(mdr);
+  mdcache->request_drop_non_rdlocks(mdr);
 
   // reply at all?
   if (client_inst.name.is_mds()) {