]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid including caps in readdir items if snaprealm differs
authorSage Weil <sage@newdream.net>
Tue, 24 Mar 2009 22:12:50 +0000 (15:12 -0700)
committerSage Weil <sage@newdream.net>
Tue, 24 Mar 2009 22:19:08 +0000 (15:19 -0700)
Since the reply snaprealm starts at the _dir_ inode, we want to
exclude caps for any nested items if the realm differs.  Otherwise
the client is screwed...

src/mds/CInode.cc
src/mds/CInode.h
src/mds/Server.cc

index de6b098bc709ae42fb35ebc528a0cf2dd4892ded..1d0b0a4eb853bbf43fe3697b2ef52682efe04c3c 100644 (file)
@@ -1341,12 +1341,19 @@ void CInode::decode_snap_blob(bufferlist& snapbl)
 
 
 bool CInode::encode_inodestat(bufferlist& bl, Session *session,
+                             SnapRealm *realm,
                              snapid_t snapid, bool is_replay)
 {
   int client = session->inst.name.num();
 
   bool valid = true;
 
+  // do not issue caps if inode differs from readdir snaprealm
+  bool no_caps = (realm && snaprealm && realm != snaprealm);
+  if (no_caps)
+    dout(20) << "encode_inodestat realm=" << realm << " snaprealm " << snaprealm
+            << " no_caps=" << no_caps << dendl;
+
   // pick a version!
   inode_t *oi = &inode;
   inode_t *pi = get_projected_inode();
@@ -1435,12 +1442,13 @@ bool CInode::encode_inodestat(bufferlist& bl, Session *session,
     e.cap.mseq = 0;
     e.cap.realm = 0;
   } else {
-    if (valid && !cap && is_auth()) {
+    if (!no_caps && valid && !cap && is_auth()) {
       // add a new cap
       cap = add_client_cap(client, session, &mdcache->client_rdcaps, find_snaprealm());
     }
 
     if (is_replay) {
+      assert(cap);
       // if this is a replayed request, check for a cap reconnect
       ceph_mds_cap_reconnect *rc = mdcache->get_replay_cap_reconnect(pi->ino, client);
       if (rc) {
index 4215e1b98668eeb47903169169b6bea34f2da6bb..c58e4c634f91fa72c93007303c88208ac24cdb69 100644 (file)
@@ -441,7 +441,8 @@ private:
   
 
   // for giving to clients
-  bool encode_inodestat(bufferlist& bl, Session *session, snapid_t snapid=CEPH_NOSNAP, bool is_replay=false);
+  bool encode_inodestat(bufferlist& bl, Session *session, SnapRealm *realm,
+                       snapid_t snapid=CEPH_NOSNAP, bool is_replay=false);
   void encode_cap_message(MClientCaps *m, Capability *cap);
 
 
index a1447dc890d4e082db58ababc4619ab59d72ce32..4677cdd8308edb48f1aac39a07844644c9f534fc 100644 (file)
@@ -733,10 +733,10 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C
     // snapbl
     realm = in->find_snaprealm();
     reply->snapbl = realm->get_snap_trace();
-    dout(10) << "set_trace_dist snaprealm " << *realm << dendl;
+    dout(10) << "set_trace_dist snaprealm " << *realm << " len=" << reply->snapbl.length() << dendl;
   }
 
-  in->encode_inodestat(bl, session, snapid, is_replay);
+  in->encode_inodestat(bl, session, NULL, snapid, is_replay);
   dout(20) << "set_trace_dist added snapid " << snapid << " " << *in << dendl;
 
   if (snapid != CEPH_NOSNAP && in == snapdiri) {
@@ -750,7 +750,7 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C
 
     // back to the live tree
     snapid = CEPH_NOSNAP;
-    in->encode_inodestat(bl, session, snapid);
+    in->encode_inodestat(bl, session, NULL, snapid);
     numi++;
     dout(20) << "set_trace_dist added snapid " << snapid << " " << *in << dendl;
 
@@ -2282,7 +2282,7 @@ void Server::handle_client_readdir(MDRequest *mdr)
 
     // inode
     dout(12) << "including inode " << *in << dendl;
-    bool valid = in->encode_inodestat(dnbl, mdr->session, snapid);
+    bool valid = in->encode_inodestat(dnbl, mdr->session, realm, snapid);
     assert(valid);
     numfiles++;
 
@@ -5275,7 +5275,7 @@ void Server::handle_client_lssnap(MDRequest *mdr)
     else
       ::encode(p->second->get_long_name(), dnbl);
     encode_infinite_lease(dnbl);
-    diri->encode_inodestat(dnbl, mdr->session, p->first);
+    diri->encode_inodestat(dnbl, mdr->session, realm, p->first);
     num++;
   }