From f9c36b5999dcb9f90fb7b97f671d077cbd9034a9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sun, 23 Nov 2008 10:57:28 -0800 Subject: [PATCH] mds: remove capless inodes from logsegment open_file lists after reconnect Inodes get added during replay of EOpen events. We remove capless inodes after reconnect restores from clients. We only want inodes with caps on those lists. Add an assertion to enforce constraint. Also, remove ourselves explicitly in remove_inode(), since that may happen during replay when an inode is destroyed. --- src/mds/MDCache.cc | 29 +++++++++++++++++++++++++++++ src/mds/MDCache.h | 3 +++ src/mds/MDS.cc | 2 ++ src/mds/journal.cc | 1 + 4 files changed, 35 insertions(+) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 576d6aa31bc9b..059705fe47bd1 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -196,6 +196,8 @@ void MDCache::remove_inode(CInode *o) if (o->is_dirty()) o->mark_clean(); + o->xlist_open_file.remove_myself(); + // remove from inode map inode_map.erase(o->vino()); @@ -3600,6 +3602,33 @@ void MDCache::send_snaps(map& splits) } +/* + * remove any items from logsegment open_file lists that don't have + * any caps + */ +void MDCache::reconnect_clean_open_file_lists() +{ + dout(10) << "reconnect_clean_open_file_lists" << dendl; + + for (map::iterator p = mds->mdlog->segments.begin(); + p != mds->mdlog->segments.end(); + p++) { + LogSegment *ls = p->second; + + xlist::iterator q = ls->open_files.begin(); + while (!q.end()) { + CInode *in = *q; + ++q; + if (!in->is_any_caps()) { + dout(10) << " unlisting capless inode " << *in << dendl; + in->xlist_open_file.remove_myself(); + } + } + } +} + + + void MDCache::rejoin_import_cap(CInode *in, int client, ceph_mds_cap_reconnect& icr, int frommds) { dout(10) << "rejoin_import_cap for client" << client << " from mds" << frommds diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index eb81f5575beac..7363ac06c9a4e 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -615,6 +615,9 @@ public: ESubtreeMap *create_subtree_map(); + // [reconnect] + void reconnect_clean_open_file_lists(); + protected: // [rejoin] set rejoin_gather; // nodes from whom i need a rejoin diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index d9957b4c6237e..8de5ba624c825 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -960,6 +960,8 @@ void MDS::reconnect_done() dout(1) << "reconnect_done" << dendl; request_state(MDSMap::STATE_REJOIN); // move to rejoin state + mdcache->reconnect_clean_open_file_lists(); + /* if (mdsmap->get_num_in_mds() == 1 && mdsmap->get_num_mds(MDSMap::STATE_FAILED) == 0) { // just me! diff --git a/src/mds/journal.cc b/src/mds/journal.cc index f5dd5f64098e3..01e2a24bf186f 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -158,6 +158,7 @@ C_Gather *LogSegment::try_to_expire(MDS *mds) for (xlist::iterator p = open_files.begin(); !p.end(); ++p) { CInode *in = *p; dout(20) << "try_to_expire requeueing open file " << *in << dendl; + assert(in->is_any_caps()); if (!le) le = new EOpen(mds->mdlog); le->add_clean_inode(in); ls->open_files.push_back(&in->xlist_open_file); -- 2.39.5