]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: use dn_hash in anchor records instead of frag_t (which may change)
authorSage Weil <sage@newdream.net>
Wed, 28 May 2008 19:23:55 +0000 (12:23 -0700)
committerSage Weil <sage@newdream.net>
Wed, 28 May 2008 19:26:16 +0000 (12:26 -0700)
src/TODO
src/include/ceph_fs.h
src/kernel/ktcp.c
src/kernel/ktcp.h
src/mds/Anchor.h
src/mds/AnchorTable.cc
src/mds/AnchorTable.h
src/mds/CDentry.cc
src/mds/CInode.cc
src/mds/MDCache.cc

index 1adfd242f31c375fce1a874031c2a85dfcb68f83..9e61c4836211af45ed626e097f005fd41df24975 100644 (file)
--- 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
index e15b1237ad91b8ab91b46c2d178b89f629e3cfff..5e62c9b01d3690c8c21f10729a329de1a9098a24 100644 (file)
@@ -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--)
index 046861d94df7052eb37e3ed4e2be85d83cbb409c..e7040ea7cf782d5f0293f75d12a46b180f59583f 100644 (file)
@@ -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;
index 840c8d5a8865b8e7dbc48f581e4e224371ae02b3..ef6650391d091cefd3e9c72ff3628797ed8f5e3f 100644 (file)
@@ -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);
 
index a87c29a40412938fd5a5d978f52b8368ca4c3225..7cdf8182fa8e2365a38f4a77f8112ebdb93a1921 100644 (file)
@@ -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
index 9d4043c2785b2d23eeeb75dffefa88f2fa26c2dc..772718097379539b88be64943b6cfbf549fa2eb3 100644 (file)
@@ -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<Anchor>& trace, int reqmd
 {
   // make sure trace is in table
   for (unsigned i=0; i<trace.size(); i++) 
-    add(trace[i].ino, trace[i].dirfrag);
+    add(trace[i].ino, trace[i].dirino, trace[i].dn_hash);
   inc(ino);
 
   version++;
@@ -200,7 +200,7 @@ void AnchorTable::commit(version_t atid)
       
       // add new
       for (unsigned i=0; i<trace.size(); i++) 
-       add(trace[i].ino, trace[i].dirfrag);
+       add(trace[i].ino, trace[i].dirino, trace[i].dn_hash);
       inc(ino);
     } else {
       dout(7) << "commit " << atid << " update " << ino << " -- DNE" << dendl;
index 64a2002ba7c85d31129f8141e6ac16f3d60f092c..520597e6de920904b6151bb97346a42196bd6b78 100644 (file)
@@ -51,7 +51,7 @@ class AnchorTable {
 protected:
 
   // basic updates
-  bool add(inodeno_t ino, dirfrag_t dirfrag);
+  bool add(inodeno_t ino, inodeno_t dirino, __u32 dn_hash);
   void inc(inodeno_t ino);
   void dec(inodeno_t ino);
 
index ab8002af9c7c5e942541d67ed79b1eb6983cb16a..95f4c7b61d1a151a47392ecd57e8b6026f611d3e 100644 (file)
@@ -240,7 +240,7 @@ void CDentry::make_anchor_trace(vector<Anchor>& 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;
 }
 
index 787440654bfb92d68bce6860b9f8325e52a53247..d5954fc16ca8341e724b804118d565281490417d 100644 (file)
@@ -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<Anchor>& 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());
 }
index 93f7ece736503c19f059a535266287a5fa6d3114..87159039fe32686f96a2039d90b0942b6b0cf408 100644 (file)
@@ -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;