From: Sage Weil Date: Wed, 28 May 2008 19:23:55 +0000 (-0700) Subject: mds: use dn_hash in anchor records instead of frag_t (which may change) X-Git-Tag: v0.3~170^2~34 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f67021eb90f6aced91c5bbab04a941c1d3cb5f0f;p=ceph.git mds: use dn_hash in anchor records instead of frag_t (which may change) --- diff --git a/src/TODO b/src/TODO index 1adfd242f31..9e61c483621 100644 --- a/src/TODO +++ b/src/TODO @@ -70,10 +70,9 @@ mds nested mds mustfix - rollback vs accounting is just broken! can we avoid it. - even with _just_ parent dir mtime, the rollback metablob isn't sufficient during replay.. we need special handling regardless. -- when renaming a dir, how do we know if we need to update the anchor table? -- anchor records need to include the dentry hash - - adjust conditional guard on anchor table updates accordingly (i.e., update table even if in same dir) + - anchor_destroy needs to xlock linklock.. which means it needs a Mutation wrapper? + - ... when it gets a caller.. someday.. - fix rm -r vs mds exports - use new dir size values in dirstat diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index e15b1237ad9..5e62c9b01d3 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -248,7 +248,7 @@ static inline unsigned long ceph_end_name_hash(unsigned long hash) /* Compute the hash for a name string. */ static inline unsigned int -ceph_full_name_hash(const unsigned char *name, unsigned int len) +ceph_full_name_hash(const char *name, unsigned int len) { unsigned long hash = ceph_init_name_hash(); while (len--) diff --git a/src/kernel/ktcp.c b/src/kernel/ktcp.c index 046861d94df..e7040ea7cf7 100644 --- a/src/kernel/ktcp.c +++ b/src/kernel/ktcp.c @@ -31,7 +31,7 @@ struct kobj_type ceph_socket_type = { .release = ceph_socket_destroy, }; -struct ceph_socket *ceph_socket_create() +static struct ceph_socket *ceph_socket_create(void) { struct ceph_socket *s; int err; diff --git a/src/kernel/ktcp.h b/src/kernel/ktcp.h index 840c8d5a886..ef6650391d0 100644 --- a/src/kernel/ktcp.h +++ b/src/kernel/ktcp.h @@ -22,7 +22,6 @@ void ceph_cancel_sock_callbacks(struct ceph_socket *); int ceph_workqueue_init(void); void ceph_workqueue_shutdown(void); -extern struct ceph_socket *ceph_socket_create(void); extern void ceph_socket_get(struct ceph_socket *s); extern void ceph_socket_put(struct ceph_socket *s, int die); diff --git a/src/mds/Anchor.h b/src/mds/Anchor.h index a87c29a4041..7cdf8182fa8 100644 --- a/src/mds/Anchor.h +++ b/src/mds/Anchor.h @@ -70,34 +70,36 @@ inline const char* get_anchor_opname(int o) { class Anchor { public: inodeno_t ino; // anchored ino - dirfrag_t dirfrag; // containing dirfrag - //string ref_dn; // referring dentry + inodeno_t dirino; + __u32 dn_hash; int nref; // reference count - Anchor() : nref(0) {} - Anchor(inodeno_t i, dirfrag_t df, - //string& rd, - int nr=0) : - ino(i), dirfrag(df), - //ref_dn(rd), + Anchor() : dn_hash(0), nref(0) {} + Anchor(inodeno_t i, inodeno_t di, __u32 hash, int nr=0) : + ino(i), dirino(di), dn_hash(hash), nref(nr) { } + Anchor(inodeno_t i, inodeno_t di, const string &dname, int nr=0) : + ino(i), dirino(di), + dn_hash(ceph_full_name_hash(dname.data(), dname.length())), nref(nr) { } void encode(bufferlist &bl) const { ::encode(ino, bl); - ::encode(dirfrag, bl); + ::encode(dirino, bl); + ::encode(dn_hash, bl); ::encode(nref, bl); } void decode(bufferlist::iterator &bl) { ::decode(ino, bl); - ::decode(dirfrag, bl); + ::decode(dirino, bl); + ::decode(dn_hash, bl); ::decode(nref, bl); } }; WRITE_CLASS_ENCODER(Anchor) -inline ostream& operator<<(ostream& out, Anchor& a) +inline ostream& operator<<(ostream& out, const Anchor &a) { - return out << "a(" << a.ino << " " << a.dirfrag << " " << a.nref << ")"; + return out << "a(" << a.ino << " " << a.dirino << "/" << a.dn_hash << " " << a.nref << ")"; } #endif diff --git a/src/mds/AnchorTable.cc b/src/mds/AnchorTable.cc index 9d4043c2785..77271809737 100644 --- a/src/mds/AnchorTable.cc +++ b/src/mds/AnchorTable.cc @@ -45,17 +45,17 @@ void AnchorTable::dump() * basic updates */ -bool AnchorTable::add(inodeno_t ino, dirfrag_t dirfrag) +bool AnchorTable::add(inodeno_t ino, inodeno_t dirino, __u32 dn_hash) { //dout(17) << "add " << ino << " dirfrag " << dirfrag << dendl; // parent should be there - assert(dirfrag.ino < MDS_INO_BASE || // system dirino - anchor_map.count(dirfrag.ino)); // have + assert(dirino < MDS_INO_BASE || // base case, + anchor_map.count(dirino)); // or have it if (anchor_map.count(ino) == 0) { // new item - anchor_map[ino] = Anchor(ino, dirfrag); + anchor_map[ino] = Anchor(ino, dirino, dn_hash); dout(7) << "add added " << anchor_map[ino] << dendl; return true; } else { @@ -75,7 +75,7 @@ void AnchorTable::inc(inodeno_t ino) anchor.nref++; dout(10) << "inc now " << anchor << dendl; - ino = anchor.dirfrag.ino; + ino = anchor.dirino; if (ino == 0) break; if (anchor_map.count(ino) == 0) break; @@ -93,12 +93,12 @@ void AnchorTable::dec(inodeno_t ino) if (anchor.nref == 0) { dout(10) << "dec removing " << anchor << dendl; - dirfrag_t dirfrag = anchor.dirfrag; + inodeno_t dirino = anchor.dirino; anchor_map.erase(ino); - ino = dirfrag.ino; + ino = dirino; } else { dout(10) << "dec now " << anchor << dendl; - ino = anchor.dirfrag.ino; + ino = anchor.dirino; } if (ino == 0) break; @@ -127,8 +127,8 @@ void AnchorTable::handle_lookup(MAnchor *req) dout(10) << "handle_lookup adding " << anchor << dendl; trace.insert(trace.begin(), anchor); // lame FIXME - if (anchor.dirfrag.ino < MDS_INO_BASE) break; - curino = anchor.dirfrag.ino; + if (anchor.dirino < MDS_INO_BASE) break; + curino = anchor.dirino; } // reply @@ -146,7 +146,7 @@ void AnchorTable::create_prepare(inodeno_t ino, vector& trace, int reqmd { // make sure trace is in table for (unsigned i=0; i& trace, CInode *in) dir->inode->make_anchor_trace(trace); // add this inode (in my dirfrag) to the end - trace.push_back(Anchor(in->ino(), dir->dirfrag())); + trace.push_back(Anchor(in->ino(), dir->ino(), name)); dout(10) << "make_anchor_trace added " << trace.back() << dendl; } diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 787440654bf..d5954fc16ca 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -149,7 +149,7 @@ frag_t CInode::pick_dirfrag(const string& dn) if (dirfragtree.empty()) return frag_t(); // avoid the string hash if we can. - __u32 h = ceph_full_name_hash((const unsigned char *)dn.data(), dn.length()); + __u32 h = ceph_full_name_hash(dn.data(), dn.length()); return dirfragtree[h*h]; } @@ -393,11 +393,8 @@ void CInode::make_path(filepath& fp) void CInode::make_anchor_trace(vector& trace) { - if (parent) { - parent->dir->inode->make_anchor_trace(trace); - trace.push_back(Anchor(ino(), parent->dir->dirfrag())); - dout(10) << "make_anchor_trace added " << trace.back() << dendl; - } + if (parent) + parent->make_anchor_trace(trace, this); else assert(is_root() || is_stray()); } diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 93f7ece7365..87159039fe3 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -4472,15 +4472,15 @@ void MDCache::open_remote_ino_2(inodeno_t ino, if (in) break; i--; if (!i) { - in = get_inode(anchortrace[i].dirfrag.ino); + in = get_inode(anchortrace[i].dirino); if (!in) { - dout(0) << "open_remote_ino_2 don't have inode " << anchortrace[i].dirfrag.ino << dendl; - if (anchortrace[i].dirfrag.ino == MDS_INO_ROOT) { + dout(0) << "open_remote_ino_2 don't have dir inode " << anchortrace[i].dirino << dendl; + if (anchortrace[i].dirino == MDS_INO_ROOT) { open_root(onfinish); return; } - if (MDS_INO_IS_STRAY(anchortrace[i].dirfrag.ino)) { - int mds = anchortrace[i].dirfrag.ino % MAX_MDS; + if (MDS_INO_IS_STRAY(anchortrace[i].dirino)) { + int mds = anchortrace[i].dirino % MAX_MDS; open_foreign_stray(mds, onfinish); return; } @@ -4500,7 +4500,7 @@ void MDCache::open_remote_ino_2(inodeno_t ino, } // open dirfrag beneath *in - frag_t frag = anchortrace[i].dirfrag.frag; + frag_t frag = in->dirfragtree[anchortrace[i].dn_hash]; if (!in->dirfragtree.contains(frag)) { dout(10) << "frag " << frag << " not valid, requerying anchortable" << dendl; @@ -4512,7 +4512,7 @@ void MDCache::open_remote_ino_2(inodeno_t ino, if (!dir && !in->is_auth()) { dout(10) << "opening remote dirfrag " << frag << " under " << *in << dendl; - /* FIXME: we re-query the anchortable just to avoid a fragtree update race */ + /* we re-query the anchortable just to avoid a fragtree update race */ open_remote_dirfrag(in, frag, new C_MDC_RetryOpenRemoteIno(this, ino, mdr, onfinish)); return;