From c8015dfb1d28c41797a7b7c3ac4f7aee9f717fcf Mon Sep 17 00:00:00 2001 From: sageweil Date: Wed, 27 Jun 2007 02:35:23 +0000 Subject: [PATCH] * fixed up indoe/dentry/dir discover; all now add_replica_*() * fixed bug with discover auth hints * cleaned up handle_discover_reply git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1448 29311d96-e01e-0410-9327-a35deaab8ce9 --- branches/sage/cephmds2/TODO | 8 +- branches/sage/cephmds2/mds/CDentry.h | 9 +- branches/sage/cephmds2/mds/CInode.h | 3 +- branches/sage/cephmds2/mds/MDCache.cc | 193 +++++++++++-------------- branches/sage/cephmds2/mds/MDCache.h | 4 + branches/sage/cephmds2/mds/Migrator.cc | 11 +- 6 files changed, 102 insertions(+), 126 deletions(-) diff --git a/branches/sage/cephmds2/TODO b/branches/sage/cephmds2/TODO index 44f1c36f58f69..aba14d83dd42d 100644 --- a/branches/sage/cephmds2/TODO +++ b/branches/sage/cephmds2/TODO @@ -47,12 +47,8 @@ sage doc sage mds -- unlink needs to adjust anchortable - -/- rename_prep needs to do a CDentryDiscover on straydn. and a CDirDiscover while we're at it! - -/- slave request cleanup on failure -/ - flag request, and discard on re-dispatch? (cuz it'll be waiting on random stuff) +?- inode replicate/discover versus lock state +?- dentry replicate/discover versus lock state /- fix slave op commit/abort logic: / - recovering node needs to know what stray prepare ops committed diff --git a/branches/sage/cephmds2/mds/CDentry.h b/branches/sage/cephmds2/mds/CDentry.h index c2e6c03eae9e7..fe7cb7393252a 100644 --- a/branches/sage/cephmds2/mds/CDentry.h +++ b/branches/sage/cephmds2/mds/CDentry.h @@ -246,7 +246,6 @@ class CDentryDiscover { int replica_nonce; int lockstate; - //inodeno_t ino; inodeno_t remote_ino; public: @@ -254,7 +253,6 @@ public: CDentryDiscover(CDentry *dn, int nonce) : dname(dn->get_name()), replica_nonce(nonce), lockstate(dn->lock.get_replica_state()), - //ino(dn->get_ino()), remote_ino(dn->get_remote_ino()) { } string& get_dname() { return dname; } @@ -264,17 +262,13 @@ public: void update_dentry(CDentry *dn) { dn->set_replica_nonce( replica_nonce ); - if (remote_ino) - dn->set_remote_ino(remote_ino); } - void update_new_dentry(CDentry *dn) { - update_dentry(dn); + void init_dentry_lock(CDentry *dn) { dn->lock.set_state( lockstate ); } void _encode(bufferlist& bl) { ::_encode(dname, bl); - //::_encode(ino, bl); ::_encode(remote_ino, bl); ::_encode(replica_nonce, bl); ::_encode(lockstate, bl); @@ -282,7 +276,6 @@ public: void _decode(bufferlist& bl, int& off) { ::_decode(dname, bl, off); - //::_decode(ino, bl, off); ::_decode(remote_ino, bl, off); ::_decode(replica_nonce, bl, off); ::_decode(lockstate, bl, off); diff --git a/branches/sage/cephmds2/mds/CInode.h b/branches/sage/cephmds2/mds/CInode.h index 1310b9c236706..4bc00344f7726 100644 --- a/branches/sage/cephmds2/mds/CInode.h +++ b/branches/sage/cephmds2/mds/CInode.h @@ -469,8 +469,9 @@ class CInodeDiscover { in->inode = inode; in->symlink = symlink; in->dirfragtree = dirfragtree; - in->replica_nonce = replica_nonce; + } + void init_inode_locks(CInode *in) { in->authlock.set_state(authlock_state); in->linklock.set_state(linklock_state); in->dirfragtreelock.set_state(dirfragtreelock_state); diff --git a/branches/sage/cephmds2/mds/MDCache.cc b/branches/sage/cephmds2/mds/MDCache.cc index 9f00dac3b521a..fee745ed4999f 100644 --- a/branches/sage/cephmds2/mds/MDCache.cc +++ b/branches/sage/cephmds2/mds/MDCache.cc @@ -2766,7 +2766,7 @@ void MDCache::handle_cache_expire(MCacheExpire *m) if (nonce == dn->get_replica_nonce(from)) { dout(7) << " dentry_expire on " << *dn << " from mds" << from << endl; - dn->remove_replica(from); + dentry_remove_replica(dn, from); } else { dout(7) << " dentry_expire on " << *dn << " from mds" << from @@ -3214,7 +3214,8 @@ int MDCache::path_traverse(MDRequest *mdr, Message *req, // who mds->send_message_mds(new MDiscover(mds->get_nodeid(), cur->ino(), want, - true), // need this dir too + true, // need this dir! + onfail == MDS_TRAVERSE_DISCOVERXLOCK), cur->authority().first, MDS_PORT_CACHE); dir_discovers[cur->ino()].insert(cur->authority().first); } @@ -4386,12 +4387,8 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) dout(7) << "discover_reply root + " << m->get_path() << " " << m->get_num_inodes() << " inodes" << endl; // add in root - cur = new CInode(this, false); - m->get_inode(0).update_inode(cur); // that thar 0 is an array index (the 0th inode in the reply). - - // root - set_root( cur ); - add_inode( cur ); + cur = add_replica_inode(m->get_inode(0), NULL); + set_root(cur); dout(7) << "discover_reply got root " << *cur << endl; // take root waiters @@ -4400,10 +4397,9 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) else if (MDS_INO_IS_STRAY(m->get_base_ino())) { dout(7) << "discover_reply stray + " << m->get_path() << " " << m->get_num_inodes() << " inodes" << endl; - // add in root - cur = new CInode(this, false); - m->get_inode(0).update_inode(cur); // that thar 0 is an array index (the 0th inode in the reply). - add_inode( cur ); + // add + cur = add_replica_inode(m->get_inode(0), NULL); + set_root(cur); dout(7) << "discover_reply got stray " << *cur << endl; // take waiters @@ -4428,20 +4424,22 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) for (int i=m->has_base_inode(); iget_depth(); i++) { dout(10) << "discover_reply i=" << i << " cur " << *cur << endl; + // dir frag_t fg; CDir *curdir = 0; - - // dir - if ((i > 0) || - (i == 0 && m->has_base_dir())) { + if (i > 0 || m->has_base_dir()) { assert(m->get_dir(i).get_dirfrag().ino == cur->ino()); fg = m->get_dir(i).get_dirfrag().frag; - + // add/update the dir replica curdir = add_replica_dir(cur, fg, m->get_dir(i), m->get_source().num(), finished); - } + } + if (!curdir) { + fg = cur->pick_dirfrag(m->get_dentry(i).get_dname()); + curdir = cur->get_dirfrag(fg); + } // dentry error? if (i == m->get_depth()-1 && @@ -4460,73 +4458,27 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) break; } - if (i >= m->get_last_dentry()) break; - - // dentry - dout(7) << "i = " << i << " dentry is " << m->get_dentry(i).get_dname() << endl; - - if (!curdir) { - fg = cur->pick_dirfrag(m->get_dentry(i).get_dname()); - curdir = cur->get_dirfrag(fg); - } assert(curdir); + // dentry CDentry *dn = 0; - if (i > 0 || - m->has_base_dentry()) { - dn = curdir->lookup( m->get_dentry(i).get_dname() ); - - if (dn) { - dout(7) << "had " << *dn << endl; - m->get_dentry(i).update_dentry(dn); - } else { - dn = curdir->add_dentry( m->get_dentry(i).get_dname(), 0 ); - m->get_dentry(i).update_new_dentry(dn); - dout(7) << "added " << *dn << endl; - } - - curdir->take_dentry_waiting(m->get_dentry(i).get_dname(), finished); + if (i >= m->get_last_dentry()) break; + if (i > 0 || m->has_base_dentry()) { + dn = add_replica_dentry(curdir, m->get_dentry(i), finished); } - - if (i >= m->get_last_inode()) break; // inode - dout(7) << "i = " << i << " ino is " << m->get_ino(i) << endl; - CInode *in = get_inode( m->get_inode(i).get_ino() ); - assert(dn); - - if (in) { - dout(7) << "had " << *in << ", new nonce " << m->get_inode(i).get_replica_nonce() << endl; - in->replica_nonce = m->get_inode(i).get_replica_nonce(); - - assert(in == dn->inode); // if we have it, it should be already linked to *dn. - } - else { - // didn't have it. - in = new CInode(this, false); - m->get_inode(i).update_inode(in); - add_inode( in ); - - // link in - assert(dn->inode == 0); // better not be something else linked to this dentry. - dn->dir->link_inode(dn, in); - - dout(7) << "added " << *in << " nonce " << in->replica_nonce << endl; - } - - // onward! - cur = in; + if (i >= m->get_last_inode()) break; + cur = add_replica_inode(m->get_inode(i), dn); } // dir_auth hint? if (m->get_dir_auth_hint() != CDIR_AUTH_UNKNOWN && m->get_dir_auth_hint() != mds->get_nodeid()) { dout(7) << " dir_auth_hint is " << m->get_dir_auth_hint() << endl; - // let's try again. - int hint = m->get_dir_auth_hint(); - - // include dentry _and_ dirfrag, just in case + // try again. include dentry _and_ dirfrag, just in case. + int hint = m->get_dir_auth_hint(); filepath want; want.push_dentry(m->get_error_dentry()); MDiscover *dis = new MDiscover(mds->get_nodeid(), @@ -4536,7 +4488,6 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) m->get_wanted_xlocks_hint()); frag_t fg = cur->pick_dirfrag(m->get_error_dentry()); dis->set_base_dir_frag(fg); - mds->send_message_mds(dis, hint, MDS_PORT_CACHE); // note the dangling discover @@ -4549,11 +4500,9 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) cur->take_waiting(CInode::WAIT_DIR, error); dir_discovers.erase(cur->ino()); } - - + // finish errors directly finish_contexts(error, -ENOENT); - mds->queue_waiters(finished); // done @@ -4607,28 +4556,77 @@ CDir *MDCache::forge_replica_dir(CInode *diri, frag_t fg, int from) return dir; } - + +CDentry *MDCache::add_replica_dentry(CDir *dir, CDentryDiscover &dis, list& finished) +{ + CDentry *dn = dir->lookup( dis.get_dname() ); + + // have it? + if (dn) { + dis.update_dentry(dn); + dout(7) << "add_replica_dentry had " << *dn << endl; + } else { + dn = dir->add_dentry( dis.get_dname(), 0 ); + dis.update_dentry(dn); + dis.init_dentry_lock(dn); + dout(7) << "add_replica_dentry added " << *dn << endl; + } + + // remote_ino linkage? + if (dis.get_remote_ino()) { + if (dn->is_null()) + dir->link_inode(dn, dis.get_remote_ino()); + + // hrm. yeah. + assert(dn->is_remote() && dn->get_remote_ino() == dis.get_remote_ino()); + } + + dir->take_dentry_waiting(dis.get_dname(), finished); + + return dn; +} + +CInode *MDCache::add_replica_inode(CInodeDiscover& dis, CDentry *dn) +{ + CInode *in = get_inode(dis.get_ino()); + if (!in) { + in = new CInode(this, false); + dis.update_inode(in); + dis.init_inode_locks(in); + add_inode(in); + dout(10) << "add_replica_inode had " << *in << endl; + if (dn && dn->is_null()) + dn->dir->link_inode(dn, in); + } else { + dis.update_inode(in); + dout(10) << "add_replica_inode added " << *in << endl; + } + + if (dn) { + assert(dn->is_primary()); + assert(dn->inode == in); + } + + return in; +} + CDentry *MDCache::add_replica_stray(bufferlist &bl, CInode *in, int from) { + list finished; int off = 0; // inode CInodeDiscover indis; indis._decode(bl, off); - CInode *strayin = get_inode(indis.get_ino()); - if (!strayin) - strayin = new CInode(this, false); - indis.update_inode(strayin); + CInode *strayin = add_replica_inode(indis, NULL); dout(15) << "strayin " << *strayin << endl; // dir CDirDiscover dirdis; dirdis._decode(bl, off); - list finished; CDir *straydir = add_replica_dir(strayin, dirdis.get_dirfrag().frag, dirdis, from, finished); - mds->queue_waiters(finished); dout(15) << "straydir " << *straydir << endl; // dentry @@ -4637,15 +4635,9 @@ CDentry *MDCache::add_replica_stray(bufferlist &bl, CInode *in, int from) string straydname; in->name_stray_dentry(straydname); - CDentry *straydn = straydir->lookup(straydname); - if (straydn) { - dout(10) << "had straydn " << *straydn << endl; - dndis.update_dentry(straydn); - } else { - straydn = straydir->add_dentry( dndis.get_dname(), 0 ); - dndis.update_new_dentry(straydn); - dout(10) << "added straydn " << *straydn << endl; - } + CDentry *straydn = add_replica_dentry(straydir, dndis, finished); + + mds->queue_waiters(finished); return straydn; } @@ -4806,25 +4798,12 @@ void MDCache::handle_dentry_unlink(MDentryUnlink *m) // move to stray? CDentry *straydn = 0; if (m->strayin) { - // inode - CInode *in = get_inode(MDS_INO_STRAY(m->get_source().num())); - if (!in) { - in = new CInode(this, false); - m->strayin->update_inode(in); - add_inode(in); - } else { - m->strayin->update_inode(in); - } - - // dirfrag list finished; + CInode *in = add_replica_inode(*m->strayin, NULL); CDir *dir = add_replica_dir(in, m->straydir->get_dirfrag().frag, *m->straydir, m->get_source().num(), finished); + straydn = add_replica_dentry(dir, *m->straydn, finished); if (!finished.empty()) mds->queue_waiters(finished); - - // dentry - straydn = dir->add_dentry( m->straydn->get_dname(), 0 ); - m->straydn->update_new_dentry(straydn); } // open inode? diff --git a/branches/sage/cephmds2/mds/MDCache.h b/branches/sage/cephmds2/mds/MDCache.h index 6d08495fe98e9..7f7ccf51b86b8 100644 --- a/branches/sage/cephmds2/mds/MDCache.h +++ b/branches/sage/cephmds2/mds/MDCache.h @@ -531,6 +531,10 @@ protected: int from, list& finished); CDir* forge_replica_dir(CInode *diri, frag_t fg, int from); + + CDentry *add_replica_dentry(CDir *dir, CDentryDiscover &dis, list& finished); + CInode *add_replica_inode(CInodeDiscover& dis, CDentry *dn); + public: CDentry *add_replica_stray(bufferlist &bl, CInode *strayin, int from); protected: diff --git a/branches/sage/cephmds2/mds/Migrator.cc b/branches/sage/cephmds2/mds/Migrator.cc index 2350b1a518fa1..2973b6b404675 100644 --- a/branches/sage/cephmds2/mds/Migrator.cc +++ b/branches/sage/cephmds2/mds/Migrator.cc @@ -368,13 +368,15 @@ void Migrator::show_importing() p++) { CDir *dir = mds->mdcache->get_dirfrag(p->first); if (dir) { - dout(10) << "importing: (" << p->second << ") " << get_import_statename(p->second) + dout(10) << "importing to " << import_peer[p->first] + << ": (" << p->second << ") " << get_import_statename(p->second) << " " << p->first + << " " << *dir << endl; } else { - dout(10) << "importing: (" << p->second << ") " << get_import_statename(p->second) + dout(10) << "importing to " << import_peer[p->first] + << ": (" << p->second << ") " << get_import_statename(p->second) << " " << p->first - << " " << *dir << endl; } } @@ -386,7 +388,8 @@ void Migrator::show_exporting() for (map::iterator p = export_state.begin(); p != export_state.end(); p++) - dout(10) << "exporting: (" << p->second << ") " << get_export_statename(p->second) + dout(10) << "exporting to " << export_peer[p->first] + << ": (" << p->second << ") " << get_export_statename(p->second) << " " << p->first->dirfrag() << " " << *p->first << endl; -- 2.39.5