]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: handle MDS 'force readonly' message
authorYan, Zheng <zyan@redhat.com>
Fri, 28 Nov 2014 13:13:25 +0000 (21:13 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 2 Dec 2014 02:47:23 +0000 (10:47 +0800)
make client return -EROFS for write when MDS is readonly, instead of
waiting forever.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/MetaSession.h

index 6b43ccce38960058a2f641da58ca9010839fc269..dffbb61645e21936ce8d821851e343bfa2325887 100644 (file)
@@ -1752,6 +1752,10 @@ void Client::handle_client_session(MClientSession *m)
     session->con->send_message(new MClientSession(CEPH_SESSION_FLUSHMSG_ACK, m->get_seq()));
     break;
 
+  case CEPH_SESSION_FORCE_RO:
+    force_session_readonly(session);
+    break;
+
   default:
     assert(0);
   }
@@ -2148,6 +2152,8 @@ void Client::send_reconnect(MetaSession *session)
   // trim unused caps to reduce MDS's cache rejoin time
   trim_cache_for_reconnect(session);
 
+  session->readonly = false;
+
   if (session->release) {
     session->release->put();
     session->release = NULL;
@@ -2541,6 +2547,10 @@ int Client::get_caps(Inode *in, int need, int want, int *phave, loff_t endoff)
       }
       ldout(cct, 10) << "waiting for caps need " << ccap_string(need) << " want " << ccap_string(want) << dendl;
     }
+
+    if ((need & CEPH_CAP_FILE_WR) && in->auth_cap &&
+       in->auth_cap->session->readonly)
+      return -EROFS;
     
     wait_on_list(in->waitfor_caps);
   }
@@ -3353,6 +3363,16 @@ void Client::trim_caps(MetaSession *s, int max)
     _invalidate_kernel_dcache();
 }
 
+void Client::force_session_readonly(MetaSession *s)
+{
+  s->readonly = true;
+  for (xlist<Cap*>::iterator p = s->caps.begin(); !p.end(); ++p) {
+    Inode *in = (*p)->inode;
+    if (in->caps_wanted() & CEPH_CAP_FILE_WR)
+      signal_cond_list(in->waitfor_caps);
+  }
+}
+
 void Client::mark_caps_dirty(Inode *in, int caps)
 {
   ldout(cct, 10) << "mark_caps_dirty " << *in << " " << ccap_string(in->dirty_caps) << " -> "
index 4afc206077d530150f2907fa2d4a8f84259c3f41..96807a6d33e34f8275d7b1c9d9e76ccc2b9bc147 100644 (file)
@@ -433,7 +433,10 @@ protected:
   
   void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);
   void dump_cache(Formatter *f);  // debug
-  
+
+  // force read-only
+  void force_session_readonly(MetaSession *s);
+
   // trace generation
   ofstream traceout;
 
index 6eb813cb22d4e1c4c5e6be033c956af3282fa2f5..1e0d17b0a9e0b6295c383972692fcfeeab5ebc9d 100644 (file)
@@ -37,6 +37,8 @@ struct MetaSession {
     STATE_STALE,
   } state;
 
+  bool readonly;
+
   list<Context*> waiting_for_open;
 
   xlist<Cap*> caps;
@@ -52,7 +54,7 @@ struct MetaSession {
   MetaSession()
     : mds_num(-1), con(NULL),
       seq(0), cap_gen(0), cap_renew_seq(0), num_caps(0),
-      state(STATE_NEW), s_cap_iterator(NULL),
+      state(STATE_NEW), readonly(false), s_cap_iterator(NULL),
       release(NULL)
   {}
   ~MetaSession();