]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: properly handle ESTALE by redirecting to auth MDS
authorGreg Farnum <gregf@hq.newdream.net>
Mon, 21 Jun 2010 23:27:32 +0000 (16:27 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Mon, 21 Jun 2010 23:27:59 +0000 (16:27 -0700)
src/client/Client.cc
src/client/Client.h

index c2a8c39194447df097965c7b20f29502d54e8dc3..9bc89285fb0c3a93a9ee25ffd35ef4f91a6d43a8 100644 (file)
@@ -764,7 +764,7 @@ int Client::choose_target_mds(MetaRequest *req)
       dout(0) << "hack: sending all requests to mds" << mds << dendl;
     }
   } else {
-    if (req->auth_is_best()) {
+    if (req->auth_is_best() || req->send_to_auth) {
       // pick the actual auth (as best we can)
       if (item) {
        mds = item->authority();
@@ -1129,6 +1129,9 @@ void Client::send_request(MetaRequest *request, int mds)
   }
   request->mds = mds;
 
+  if (request->inode && request->inode->caps.count(mds))
+    request->sent_on_mseq = request->inode->caps[mds]->mseq;
+
   mds_sessions[mds].requests.push_back(&request->item);
 
   dout(10) << "send_request " << *r << " to mds" << mds << dendl;
@@ -1194,6 +1197,20 @@ void Client::handle_client_reply(MClientReply *reply)
     reply->put();
     return;
   }
+
+  if (-ESTALE == reply->get_result()) { //see if we can get to proper MDS
+    request->send_to_auth = true;
+    request->resend_mds = choose_target_mds(request);
+    if (request->resend_mds != request->mds) { //wasn't sent to auth, resend
+      send_request(request, request->resend_mds);
+      return;
+    } else if (request->inode->caps.count(request->resend_mds) &&
+              request->sent_on_mseq != request->inode->caps[request->resend_mds]->mseq) {
+      //auth data out of date; send it again!
+      send_request(request, request->resend_mds);
+      return; 
+    }
+  }
   
   int mds = reply->get_source().num();
   request->reply = reply;
index 888d26c6218a672d452883ba20ac8d8aa50449c4..bd7c6b3363a1acf3a8a2427abba40455ab5f6435 100644 (file)
@@ -113,6 +113,8 @@ struct MetaRequest {
   utime_t  sent_stamp;
   int      mds;                // who i am asking
   int      resend_mds;         // someone wants you to (re)send the request here
+  bool     send_to_auth;       // must send to auth mds
+  __u32    sent_on_mseq;       // mseq at last submission of this request
   int      num_fwd;            // # of times i've been forwarded
   int      retry_attempt;
   int      ref;
@@ -140,7 +142,8 @@ struct MetaRequest {
     old_dentry_drop(0), old_dentry_unless(0),
     inode(NULL), old_inode(NULL),
     dentry(NULL), old_dentry(NULL),
-    mds(-1), resend_mds(-1), num_fwd(0), retry_attempt(0),
+    mds(-1), resend_mds(-1), send_to_auth(false), sent_on_mseq(0),
+    num_fwd(0), retry_attempt(0),
     ref(1), reply(0), 
     kick(false), got_safe(false), got_unsafe(false), item(this), unsafe_item(this),
     lock("MetaRequest lock"),