From 416cc9db01aa0cd9a10e994ffa56ca93a37afdef Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 24 Mar 2009 15:12:50 -0700 Subject: [PATCH] mds: avoid including caps in readdir items if snaprealm differs 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 | 10 +++++++++- src/mds/CInode.h | 3 ++- src/mds/Server.cc | 10 +++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index de6b098bc709a..1d0b0a4eb853b 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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) { diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 4215e1b98668e..c58e4c634f91f 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -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); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index a1447dc890d4e..4677cdd8308ed 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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++; } -- 2.39.5