From fbd11d91b99b16baecb66b6c755e732a7d10d105 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 14 Apr 2009 06:48:51 -0700 Subject: [PATCH] mds: hide stray dentries and inodes that are purging Otherwise we get unwanted references when the inode is supposed to die. --- src/mds/CInode.h | 1 + src/mds/MDCache.cc | 3 +++ src/mds/Server.cc | 19 +++++++++++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 6e2f0a4d27b30..c7594301c1aba 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -112,6 +112,7 @@ class CInode : public MDSCacheObject { static const int STATE_NEEDSRECOVER = (1<<11); static const int STATE_RECOVERING = (1<<12); static const int STATE_NO_SIZE_CHECK = (1<<13); + static const int STATE_PURGING = (1<<14); // -- waiters -- static const __u64 WAIT_DIR = (1<<0); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 7adf5cf8e4e0d..8aa3be98a6ad7 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -5538,6 +5538,8 @@ int MDCache::path_traverse(MDRequest *mdr, Message *req, // who } return 1; } + if (cur->state_test(CInode::STATE_PURGING)) + return -ESTALE; // start trace if (pdnvec) @@ -6753,6 +6755,7 @@ void MDCache::purge_stray(CDentry *dn) dn->state_set(CDentry::STATE_PURGING); dn->get(CDentry::PIN_PURGING); + in->state_set(CInode::STATE_PURGING); // CHEAT. there's no real need to journal our intent to purge, since diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 600f3d22e647a..eb5f3e7bf7a44 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -413,6 +413,8 @@ void Server::handle_client_reconnect(MClientReconnect *m) p != m->realms.end(); p++) { CInode *in = mdcache->get_inode(inodeno_t(p->ino)); + if (in && in->state_test(CInode::STATE_PURGING)) + continue; if (in) { assert(in->snaprealm); if (in->snaprealm->have_past_parents_open()) { @@ -438,6 +440,8 @@ void Server::handle_client_reconnect(MClientReconnect *m) mdcache->last_cap_id = p->second.capinfo.cap_id; CInode *in = mdcache->get_inode(p->first); + if (in && in->state_test(CInode::STATE_PURGING)) + continue; if (in && in->is_auth()) { // we recovered it, and it's ours. take note. dout(15) << "open cap realm " << inodeno_t(p->second.capinfo.snaprealm) @@ -1697,10 +1701,14 @@ void Server::handle_client_lookup_hash(MDRequest *mdr) MClientRequest *req = mdr->client_request; CInode *in = mdcache->get_inode(req->get_filepath().get_ino()); + if (in && in->state_test(CInode::STATE_PURGING)) { + reply_request(mdr, -ESTALE); + return; + } if (!in) { // try the directory CInode *diri = mdcache->get_inode(req->get_filepath2().get_ino()); - if (!diri) { + if (!diri || diri->state_test(CInode::STATE_PURGING)) { reply_request(mdr, -ESTALE); return; } @@ -2066,6 +2074,9 @@ void Server::handle_client_readdir(MDRequest *mdr) if (offset && strcmp(dn->get_name().c_str(), offset) <= 0) continue; + if (dn->state_test(CDentry::STATE_PURGING)) + continue; + bool dnp = dn->use_projected(client, mdr); CDentry::linkage_t *dnl = dnp ? dn->get_projected_linkage() : dn->get_linkage(); @@ -4884,7 +4895,7 @@ void Server::handle_client_lssnap(MDRequest *mdr) // traverse to path CInode *diri = mdcache->get_inode(req->get_filepath().get_ino()); - if (!diri) { + if (!diri || diri->state_test(CInode::STATE_PURGING)) { reply_request(mdr, -ESTALE); return; } @@ -4965,7 +4976,7 @@ void Server::handle_client_mksnap(MDRequest *mdr) MClientRequest *req = mdr->client_request; CInode *diri = mdcache->get_inode(req->get_filepath().get_ino()); - if (!diri) { + if (!diri || diri->state_test(CInode::STATE_PURGING)) { reply_request(mdr, -ESTALE); return; } @@ -5133,7 +5144,7 @@ void Server::handle_client_rmsnap(MDRequest *mdr) MClientRequest *req = mdr->client_request; CInode *diri = mdcache->get_inode(req->get_filepath().get_ino()); - if (!diri) { + if (!diri || diri->state_test(CInode::STATE_PURGING)) { reply_request(mdr, -ESTALE); return; } -- 2.39.5