]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
MDRequest cleanup; partially implemented slave rename in-memory rollback; fix autosca...
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Fri, 12 Oct 2007 18:31:55 +0000 (18:31 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Fri, 12 Oct 2007 18:31:55 +0000 (18:31 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1926 29311d96-e01e-0410-9327-a35deaab8ce9

branches/sage/mds/TODO
branches/sage/mds/mds/Locker.cc
branches/sage/mds/mds/Locker.h
branches/sage/mds/mds/MDCache.cc
branches/sage/mds/mds/MDCache.h
branches/sage/mds/mds/Migrator.cc
branches/sage/mds/mds/Server.cc
branches/sage/mds/valgrind.supp

index 11e3021339b0e513c2e71fa61c84d4ea4ba38927..c4f9b16383dc96ed58ada164c643a8d7ba2dfa2a 100644 (file)
@@ -75,33 +75,31 @@ if (0) {
 
 
 mds bugs
-???- fix server unlink .. needs to use slave_requests to clean up any failures during the resolve stage
+- open file rejournaling vs capped log...
+  - open files vs shutdown in general!  need to export any caps on replicated metadata
+- export caps to auth on unlinked inodes
+- stray purge on shutdown
+
+- rename slave in-memory rollback on failure
+
 - fix purge_stray bug
 - try_remove_unlinked_dn thing
-- emetablob playback with bad linkage.. from sloppy unlink?  hmm
+
 - client session open from locker.. doesn't work properly with delays
+ -> journal the session open _with_ the import(start)
 
 - proper handling of cache expire messages during rejoin phase?
 
 - verify once-per-segment jouranl context is working...
 
-- open file rejournaling vs capped log...
-  - open files vs shutdown in general!  need to export any caps on replicated metadata
-
-mds cleanup
-- fix freeze_* interface to pull waiters _outside_
-- get rid of replicate objects for replicate_to .. encode to bufferlists directly
-
 mds
 - extend/clean up filepath to allow paths relative to an ino
   - fix path_traverse
   - fix reconnect/rejoin open file weirdness
 
-- export caps to auth on unlinked inodes
+- get rid of replicate objects for replicate_to .. encode to bufferlists directly
 
 - stray reintegration
-- stray purge on shutdown
-  - need to export stray crap to another mds..
 - verify stray is empty on shutdown
 
 - real chdir (directory "open")
@@ -118,8 +116,6 @@ mds
  
 - osd needs a set_floor_and_read op for safe failover/STOGITH-like semantics.
 
-- EMetablob should return 'expired' if they have higher versions (and are thus described by a newer journal entry)
-
 - could mark dir complete in EMetaBlob by counting how many dentries are dirtied in the current log epoch in CDir...
 
 - fix rmdir empty exported dirfrag race
@@ -135,7 +131,6 @@ mds
   - in particular, i care about dirfragtree.. get it on rejoin?
   - and dir sizes, if i add that... also on rejoin?
 
-- chdir (directory opens!)
 - efficient stat for single writers
 - lstat vs stat?
 - add FILE_CAP_EXTEND capability bit
index e7655cdd4d97d22216b9ce8e975529c0d5335639..157ef188dabb52fd81eaf44bcc4331967a1ca6fe 100644 (file)
@@ -241,8 +241,8 @@ bool Locker::acquire_locks(MDRequest *mdr,
       mds->send_message_mds(req, p->first, MDS_PORT_SERVER);
 
       // put in waiting list
-      assert(mdr->waiting_on_slave.count(p->first) == 0);
-      mdr->waiting_on_slave.insert(p->first);
+      assert(mdr->more()->waiting_on_slave.count(p->first) == 0);
+      mdr->more()->waiting_on_slave.insert(p->first);
     }
     return false;
   }
@@ -1196,7 +1196,7 @@ bool Locker::simple_xlock_start(SimpleLock *lock, MDRequest *mdr)
 
     // send lock request
     int auth = lock->get_parent()->authority().first;
-    mdr->slaves.insert(auth);
+    mdr->more()->slaves.insert(auth);
     MMDSSlaveRequest *r = new MMDSSlaveRequest(mdr->reqid, MMDSSlaveRequest::OP_XLOCK);
     r->set_lock_type(lock->get_type());
     lock->get_parent()->set_object_info(r->get_object_info());
@@ -1614,6 +1614,12 @@ void Locker::scatter_eval(ScatterLock *lock)
   }
 }
 
+void Locker::note_autoscattered(ScatterLock *lock)
+{
+  dout(10) << "note_autoscattered " << *lock << " on " << *lock->get_parent() << dendl;
+  autoscattered.push_back(&lock->xlistitem_autoscattered);
+}
+
 
 /*
  * this is called by LogSegment::try_to_trim() when trying to 
@@ -1748,7 +1754,6 @@ void Locker::scatter_lock(ScatterLock *lock)
   dout(10) << "scatter_lock " << *lock
           << " on " << *lock->get_parent() << dendl;
   assert(lock->get_parent()->is_auth());
-  assert(lock->get_parent()->can_auth_pin());
   assert(lock->is_stable());
 
   switch (lock->get_state()) {
index 7867606238b34244dec709b191752a18e9591005..a69055f49449e330df26cb2b17d4e935237ca060 100644 (file)
@@ -120,6 +120,7 @@ public:
 
   void scatter_unscatter_autoscattered();
   void scatter_try_unscatter(ScatterLock *lock, Context *c);
+  void note_autoscattered(ScatterLock *lock);
 
   void scatter_lock(ScatterLock *lock);  // called by LogSegment::try_to_expire
 
index b3a7c024750d9e4dc18a6f95fd791184f93ef035..1acb43a1d6f0d19c8778b2961259aefbf9ce52cc 100644 (file)
@@ -1183,18 +1183,18 @@ void MDCache::handle_mds_failure(int who)
     
     // failed node is slave?
     if (!p->second->committing) {
-      if (p->second->witnessed.count(who)) {
+      if (p->second->more()->witnessed.count(who)) {
        dout(10) << " master request " << *p->second << " no longer witnessed by slave mds" << who
                 << dendl;
        // discard this peer's prepare (if any)
-       p->second->witnessed.erase(who);
+       p->second->more()->witnessed.erase(who);
       }
       
-      if (p->second->waiting_on_slave.count(who)) {
+      if (p->second->more()->waiting_on_slave.count(who)) {
        dout(10) << " master request " << *p->second << " waiting for slave mds" << who
                 << " to recover" << dendl;
        // retry request when peer recovers
-       p->second->waiting_on_slave.erase(who);
+       p->second->more()->waiting_on_slave.erase(who);
        mds->wait_for_active_peer(who, new C_MDS_RetryRequest(this, p->second));
       }
     }
@@ -1449,10 +1449,10 @@ void MDCache::handle_resolve_ack(MMDSResolveAck *ack)
       mds->mdlog->submit_entry(new ESlaveUpdate(mds->mdlog, "unknown", *p, from, ESlaveUpdate::OP_ROLLBACK));
     } else {
       MDRequest *mdr = request_get(*p);
-      if (mdr->slave_commit) {
-       mdr->slave_commit->finish(-1);
-       delete mdr->slave_commit;
-       mdr->slave_commit = 0;
+      if (mdr->more()->slave_commit) {
+       mdr->more()->slave_commit->finish(-1);
+       delete mdr->more()->slave_commit;
+       mdr->more()->slave_commit = 0;
       }
       if (mdr->slave_request) 
        mdr->aborted = true;
@@ -4364,10 +4364,10 @@ void MDCache::request_finish(MDRequest *mdr)
   dout(7) << "request_finish " << *mdr << dendl;
 
   // slave finisher?
-  if (mdr->slave_commit) {
-    mdr->slave_commit->finish(0);
-    delete mdr->slave_commit;
-    mdr->slave_commit = 0;
+  if (mdr->more()->slave_commit) {
+    mdr->more()->slave_commit->finish(0);
+    delete mdr->more()->slave_commit;
+    mdr->more()->slave_commit = 0;
   }
 
   if (mdr->client_request && mds->logger) {
@@ -4433,8 +4433,8 @@ void MDCache::request_cleanup(MDRequest *mdr)
 
   // clean up slaves
   //  (will implicitly drop remote dn pins)
-  for (set<int>::iterator p = mdr->slaves.begin();
-       p != mdr->slaves.end();
+  for (set<int>::iterator p = mdr->more()->slaves.begin();
+       p != mdr->more()->slaves.end();
        ++p) {
     MMDSSlaveRequest *r = new MMDSSlaveRequest(mdr->reqid, MMDSSlaveRequest::OP_FINISH);
     mds->send_message_mds(r, *p, MDS_PORT_SERVER);
index f85e8fdd6153d80e4707e3f1e5e836d997cd5ac1..74ed6d70aa685e2edd3eb07d3a34159c903cda50 100644 (file)
@@ -83,8 +83,6 @@ struct MDRequest {
 
   // -- i am a client (master) request
   MClientRequest *client_request; // client request (if any)
-  set<int> slaves;            // mds nodes that have slave requests to me (implies client_request)
-  set<int> waiting_on_slave;  // peers i'm waiting for slavereq replies from. 
 
   vector<CDentry*> trace;  // original path traversal.
   CInode *ref;             // reference inode.  if there is only one, and its path is pinned.
@@ -93,9 +91,11 @@ struct MDRequest {
   MMDSSlaveRequest *slave_request; // slave request (if one is pending; implies slave == true)
   int slave_to_mds;                // this is a slave request if >= 0.
 
-  // -- my pins and locks --
+  // -- misc --
   LogSegment *ls;  // the log segment i'm committing to
+  utime_t now;
 
+  // -- my pins and locks --
   // cache pins (so things don't expire)
   set< MDSCacheObject* > pins;
   set<CInode*> stickydirs;
@@ -116,22 +116,31 @@ struct MDRequest {
   bool committing;
   bool aborted;
 
-  // for rename/link/unlink
-  utime_t now;
-  set<int> witnessed;       // nodes who have journaled a RenamePrepare
-  map<MDSCacheObject*,version_t> pvmap;
-
-  // for rename
-  set<int> extra_witnesses; // replica list from srcdn auth (rename)
-  version_t src_reanchor_atid;  // src->dst
-  version_t dst_reanchor_atid;  // dst->stray
-  bufferlist inode_import;
-  version_t inode_import_v;
-  //CInode *inode_export;         // inode we're exporting, if any
-  //CDentry *srcdn; // srcdn, if auth, on slave
-  
-  // called when slave commits
-  Context *slave_commit;
+  struct More {
+    set<int> slaves;           // mds nodes that have slave requests to me (implies client_request)
+    set<int> waiting_on_slave; // peers i'm waiting for slavereq replies from. 
+
+    // for rename/link/unlink
+    set<int> witnessed;       // nodes who have journaled a RenamePrepare
+    map<MDSCacheObject*,version_t> pvmap;
+    
+    // for rename
+    set<int> extra_witnesses; // replica list from srcdn auth (rename)
+    version_t src_reanchor_atid;  // src->dst
+    version_t dst_reanchor_atid;  // dst->stray
+    bufferlist inode_import;
+    version_t inode_import_v;
+    CInode* destdn_was_remote_inode;
+    bool was_link_merge;
+    
+    // called when slave commits or aborts
+    Context *slave_commit;
+
+    More() : 
+      src_reanchor_atid(0), dst_reanchor_atid(0), inode_import_v(0),
+      destdn_was_remote_inode(0), was_link_merge(false),
+      slave_commit(0) { }
+  } *_more;
 
 
   // ---------------------------------------------------
@@ -140,31 +149,34 @@ struct MDRequest {
     slave_request(0), slave_to_mds(-1), 
     ls(0),
     done_locking(false), committing(false), aborted(false),
-    src_reanchor_atid(0), dst_reanchor_atid(0), inode_import_v(0),
-    //inode_export(0), srcdn(0),
-    slave_commit(0) { }
+    _more(0) {}
   MDRequest(metareqid_t ri, MClientRequest *req) : 
     reqid(ri), client_request(req), ref(0), 
     slave_request(0), slave_to_mds(-1), 
     ls(0),
     done_locking(false), committing(false), aborted(false),
-    src_reanchor_atid(0), dst_reanchor_atid(0), inode_import_v(0),
-    //inode_export(0), srcdn(0),
-    slave_commit(0) { }
+    _more(0) {}
   MDRequest(metareqid_t ri, int by) : 
     reqid(ri), client_request(0), ref(0),
     slave_request(0), slave_to_mds(by), 
     ls(0),
     done_locking(false), committing(false), aborted(false),
-    src_reanchor_atid(0), dst_reanchor_atid(0), inode_import_v(0),
-    //inode_export(0), srcdn(0),
-    slave_commit(0) { }
+    _more(0) {}
+  ~MDRequest() {
+    delete _more;
+  }
   
   bool is_master() { return slave_to_mds < 0; }
   bool is_slave() { return slave_to_mds >= 0; }
 
-  bool slave_did_prepare() { return slave_commit; }
+  More* more() { 
+    if (!_more) _more = new More();
+    return _more;
+  }
+
+  bool slave_did_prepare() { return more()->slave_commit; }
   
+
   // pin items in cache
   void pin(MDSCacheObject *o) {
     if (pins.count(o) == 0) {
index d9f64ef89a33a77aa97a669e27e8ca618587e7d5..4e4a8b774f813d62d4791a7434c2046c61744a4e 100644 (file)
@@ -112,11 +112,12 @@ public:
 void Migrator::export_empty_import(CDir *dir)
 {
   dout(7) << "export_empty_import " << *dir << dendl;
-  
+  assert(dir->is_subtree_root());
+
   if (dir->inode->is_auth()) return;
   if (!dir->is_auth()) return;
   
-  if (dir->inode->is_freezing() || dir->inode->is_frozen()) return;
+  //if (dir->inode->is_freezing() || dir->inode->is_frozen()) return;
   if (dir->is_freezing() || dir->is_frozen()) return;
   
   if (dir->get_size() > 0) {
@@ -1909,6 +1910,11 @@ void Migrator::decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int o
   //  but not until we _actually_ finish the import...
   if (in->dirlock.is_updated())
     updated_scatterlocks.push_back(&in->dirlock);
+
+  // put in autoscatter list?
+  //  this is conservative, but safe.
+  if (in->dirlock.get_state() == LOCK_SCATTER)
+    mds->locker->note_autoscattered(&in->dirlock);
   
   // adjust replica list
   //assert(!in->is_replica(oldauth));  // not true on failed export
index 6390a8ae2eed387430f0d750e7685e67a1abb2f0..c32b946a0374cfd865d8143ca161caa9d54b9796 100644 (file)
@@ -534,7 +534,7 @@ void Server::dispatch_client_request(MDRequest *mdr)
   }
 
   // we shouldn't be waiting on anyone.
-  assert(mdr->waiting_on_slave.empty());
+  assert(mdr->more()->waiting_on_slave.empty());
   
   switch (req->get_op()) {
 
@@ -620,7 +620,7 @@ void Server::handle_slave_request(MMDSSlaveRequest *m)
        SimpleLock *lock = mds->locker->get_lock(m->get_lock_type(),
                                                 m->get_object_info());
        MDRequest *mdr = mdcache->request_get(m->get_reqid());
-       mdr->slaves.insert(from);
+       mdr->more()->slaves.insert(from);
        dout(10) << "got remote xlock on " << *lock << " on " << *lock->get_parent() << dendl;
        mdr->xlocks.insert(lock);
        mdr->locks.insert(lock);
@@ -882,17 +882,17 @@ void Server::handle_slave_auth_pin_ack(MDRequest *mdr, MMDSSlaveRequest *ack)
   }
   
   // note slave
-  mdr->slaves.insert(from);
+  mdr->more()->slaves.insert(from);
 
   // clear from waiting list
-  assert(mdr->waiting_on_slave.count(from));
-  mdr->waiting_on_slave.erase(from);
+  assert(mdr->more()->waiting_on_slave.count(from));
+  mdr->more()->waiting_on_slave.erase(from);
 
   // go again?
-  if (mdr->waiting_on_slave.empty())
+  if (mdr->more()->waiting_on_slave.empty())
     dispatch_client_request(mdr);
   else 
-    dout(10) << "still waiting on slaves " << mdr->waiting_on_slave << dendl;
+    dout(10) << "still waiting on slaves " << mdr->more()->waiting_on_slave << dendl;
 }
 
 
@@ -1989,7 +1989,7 @@ void Server::_link_remote(MDRequest *mdr, CDentry *dn, CInode *targeti)
     
   // 1. send LinkPrepare to dest (journal nlink++ prepare)
   int linkauth = targeti->authority().first;
-  if (mdr->witnessed.count(linkauth) == 0) {
+  if (mdr->more()->witnessed.count(linkauth) == 0) {
     dout(10) << " targeti auth must prepare nlink++" << dendl;
 
     MMDSSlaveRequest *req = new MMDSSlaveRequest(mdr->reqid, MMDSSlaveRequest::OP_LINKPREP);
@@ -1997,8 +1997,8 @@ void Server::_link_remote(MDRequest *mdr, CDentry *dn, CInode *targeti)
     req->now = mdr->now;
     mds->send_message_mds(req, linkauth, MDS_PORT_SERVER);
 
-    assert(mdr->waiting_on_slave.count(linkauth) == 0);
-    mdr->waiting_on_slave.insert(linkauth);
+    assert(mdr->more()->waiting_on_slave.count(linkauth) == 0);
+    mdr->more()->waiting_on_slave.insert(linkauth);
     return;
   }
   dout(10) << " targeti auth has prepared nlink++" << dendl;
@@ -2155,7 +2155,7 @@ void Server::_logged_slave_link(MDRequest *mdr, CInode *targeti, utime_t old_cti
   mds->send_message_mds(reply, mdr->slave_to_mds, MDS_PORT_SERVER);
   
   // set up commit waiter
-  mdr->slave_commit = new C_MDS_SlaveLinkCommit(this, mdr, targeti, old_ctime, old_version, inc);
+  mdr->more()->slave_commit = new C_MDS_SlaveLinkCommit(this, mdr, targeti, old_ctime, old_version, inc);
 
   // done.
   delete mdr->slave_request;
@@ -2202,17 +2202,17 @@ void Server::handle_slave_link_prep_ack(MDRequest *mdr, MMDSSlaveRequest *m)
   int from = m->get_source().num();
 
   // note slave
-  mdr->slaves.insert(from);
+  mdr->more()->slaves.insert(from);
   
   // witnessed!
-  assert(mdr->witnessed.count(from) == 0);
-  mdr->witnessed.insert(from);
+  assert(mdr->more()->witnessed.count(from) == 0);
+  mdr->more()->witnessed.insert(from);
   
   // remove from waiting list
-  assert(mdr->waiting_on_slave.count(from));
-  mdr->waiting_on_slave.erase(from);
+  assert(mdr->more()->waiting_on_slave.count(from));
+  mdr->more()->waiting_on_slave.erase(from);
 
-  assert(mdr->waiting_on_slave.empty());
+  assert(mdr->more()->waiting_on_slave.empty());
 
   dispatch_client_request(mdr);  // go again!
 }
@@ -2319,12 +2319,12 @@ void Server::handle_client_unlink(MDRequest *mdr)
     dout(10) << " straydn is " << *straydn << dendl;
     assert(straydn->is_null());
 
-    if (!mdr->dst_reanchor_atid &&
+    if (!mdr->more()->dst_reanchor_atid &&
        dn->inode->is_anchored()) {
       dout(10) << "reanchoring to stray " << *dn->inode << dendl;
       vector<Anchor> trace;
       straydn->make_anchor_trace(trace, dn->inode);
-      mds->anchorclient->prepare_update(dn->inode->ino(), trace, &mdr->dst_reanchor_atid, 
+      mds->anchorclient->prepare_update(dn->inode->ino(), trace, &mdr->more()->dst_reanchor_atid, 
                                        new C_MDS_RetryRequest(mdcache, mdr));
       return;
     }
@@ -2397,8 +2397,8 @@ void Server::_unlink_local(MDRequest *mdr, CDentry *dn, CDentry *straydn)
   le->metablob.add_dir_context(dn->get_dir());
   le->metablob.add_null_dentry(dn, true);
 
-  if (mdr->dst_reanchor_atid)
-    le->metablob.add_anchor_transaction(mdr->dst_reanchor_atid);
+  if (mdr->more()->dst_reanchor_atid)
+    le->metablob.add_anchor_transaction(mdr->more()->dst_reanchor_atid);
 
   // log + wait
   journal_opens();  // journal pending opens, just in case
@@ -2444,8 +2444,8 @@ void Server::_unlink_local_finish(MDRequest *mdr,
   }
   
   // commit anchor update?
-  if (mdr->dst_reanchor_atid) 
-    mds->anchorclient->commit(mdr->dst_reanchor_atid, mdr->ls);
+  if (mdr->more()->dst_reanchor_atid) 
+    mds->anchorclient->commit(mdr->more()->dst_reanchor_atid, mdr->ls);
 
   // bump pop
   //mds->balancer->hit_dir(mdr->now, dn->dir, META_POP_DWR);
@@ -2486,7 +2486,7 @@ void Server::_unlink_remote(MDRequest *mdr, CDentry *dn)
 
   // 1. send LinkPrepare to dest (journal nlink-- prepare)
   int inauth = dn->inode->authority().first;
-  if (mdr->witnessed.count(inauth) == 0) {
+  if (mdr->more()->witnessed.count(inauth) == 0) {
     dout(10) << " inode auth must prepare nlink--" << dendl;
 
     MMDSSlaveRequest *req = new MMDSSlaveRequest(mdr->reqid, MMDSSlaveRequest::OP_UNLINKPREP);
@@ -2494,8 +2494,8 @@ void Server::_unlink_remote(MDRequest *mdr, CDentry *dn)
     req->now = mdr->now;
     mds->send_message_mds(req, inauth, MDS_PORT_SERVER);
 
-    assert(mdr->waiting_on_slave.count(inauth) == 0);
-    mdr->waiting_on_slave.insert(inauth);
+    assert(mdr->more()->waiting_on_slave.count(inauth) == 0);
+    mdr->more()->waiting_on_slave.insert(inauth);
     return;
   }
   dout(10) << " inode auth has prepared nlink--" << dendl;
@@ -2512,8 +2512,8 @@ void Server::_unlink_remote(MDRequest *mdr, CDentry *dn)
   le->metablob.add_dir_context(dn->get_dir());
   le->metablob.add_null_dentry(dn, true);
 
-  if (mdr->dst_reanchor_atid)
-    le->metablob.add_anchor_transaction(mdr->dst_reanchor_atid);
+  if (mdr->more()->dst_reanchor_atid)
+    le->metablob.add_anchor_transaction(mdr->more()->dst_reanchor_atid);
 
   // finisher
   C_MDS_unlink_remote_finish *fin = new C_MDS_unlink_remote_finish(mds, mdr, dn, dirpv);
@@ -2550,8 +2550,8 @@ void Server::_unlink_remote_finish(MDRequest *mdr,
   }
 
   // commit anchor update?
-  if (mdr->dst_reanchor_atid) 
-    mds->anchorclient->commit(mdr->dst_reanchor_atid, mdr->ls);
+  if (mdr->more()->dst_reanchor_atid) 
+    mds->anchorclient->commit(mdr->more()->dst_reanchor_atid, mdr->ls);
 
   //mds->balancer->hit_dir(mdr->now, dn->dir, META_POP_DWR);
 
@@ -2824,13 +2824,13 @@ void Server::handle_client_rename(MDRequest *mdr)
    * (currently, it can ignore rename effects, because the resolve
    * stage will sort them out.)
    */
-  set<int> witnesses = mdr->extra_witnesses;
+  set<int> witnesses = mdr->more()->extra_witnesses;
   if (srcdn->is_auth())
     srcdn->list_replicas(witnesses);
   else
     witnesses.insert(srcdn->authority().first);
   destdn->list_replicas(witnesses);
-  dout(10) << " witnesses " << witnesses << ", have " << mdr->witnessed << dendl;
+  dout(10) << " witnesses " << witnesses << ", have " << mdr->more()->witnessed << dendl;
 
   // do srcdn auth last
   int last = -1;
@@ -2841,20 +2841,20 @@ void Server::handle_client_rename(MDRequest *mdr)
        p != witnesses.end();
        ++p) {
     if (*p == last) continue;  // do it last!
-    if (mdr->witnessed.count(*p)) {
+    if (mdr->more()->witnessed.count(*p)) {
       dout(10) << " already witnessed by mds" << *p << dendl;
-    } else if (mdr->waiting_on_slave.count(*p)) {
+    } else if (mdr->more()->waiting_on_slave.count(*p)) {
       dout(10) << " already waiting on witness mds" << *p << dendl;      
     } else {
       _rename_prepare_witness(mdr, *p, srcdn, destdn, straydn);
     }
   }
-  if (!mdr->waiting_on_slave.empty())
+  if (!mdr->more()->waiting_on_slave.empty())
     return;  // we're waiting for a witness.
 
   if (last >= 0 &&
-      mdr->witnessed.count(last) == 0 &&
-      mdr->waiting_on_slave.count(last) == 0) {
+      mdr->more()->witnessed.count(last) == 0 &&
+      mdr->more()->waiting_on_slave.count(last) == 0) {
     dout(10) << " preparing last witness (srcdn auth)" << dendl;
     _rename_prepare_witness(mdr, last, srcdn, destdn, straydn);
     return;
@@ -2869,18 +2869,18 @@ void Server::handle_client_rename(MDRequest *mdr)
 
     if (srcdn->is_primary() && srcdn->inode->is_anchored() &&
        srcdn->dir != destdn->dir &&
-       !mdr->src_reanchor_atid) {
+       !mdr->more()->src_reanchor_atid) {
       dout(10) << "reanchoring src->dst " << *srcdn->inode << dendl;
       vector<Anchor> trace;
       destdn->make_anchor_trace(trace, srcdn->inode);
       
       anchorgather = new C_Gather(new C_MDS_RetryRequest(mdcache, mdr));
-      mds->anchorclient->prepare_update(srcdn->inode->ino(), trace, &mdr->src_reanchor_atid, 
+      mds->anchorclient->prepare_update(srcdn->inode->ino(), trace, &mdr->more()->src_reanchor_atid, 
                                        anchorgather->new_sub());
     }
     if (destdn->is_primary() &&
        destdn->inode->is_anchored() &&
-       !mdr->dst_reanchor_atid) {
+       !mdr->more()->dst_reanchor_atid) {
       dout(10) << "reanchoring dst->stray " << *destdn->inode << dendl;
 
       assert(straydn);
@@ -2889,7 +2889,7 @@ void Server::handle_client_rename(MDRequest *mdr)
       
       if (!anchorgather)
        anchorgather = new C_Gather(new C_MDS_RetryRequest(mdcache, mdr));
-      mds->anchorclient->prepare_update(destdn->inode->ino(), trace, &mdr->dst_reanchor_atid, 
+      mds->anchorclient->prepare_update(destdn->inode->ino(), trace, &mdr->more()->dst_reanchor_atid, 
                                        anchorgather->new_sub());
     }
 
@@ -2925,8 +2925,10 @@ void Server::_rename_finish(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDe
   _rename_apply(mdr, srcdn, destdn, straydn);
   
   // commit anchor updates?
-  if (mdr->src_reanchor_atid) mds->anchorclient->commit(mdr->src_reanchor_atid, mdr->ls);
-  if (mdr->dst_reanchor_atid) mds->anchorclient->commit(mdr->dst_reanchor_atid, mdr->ls);
+  if (mdr->more()->src_reanchor_atid) 
+    mds->anchorclient->commit(mdr->more()->src_reanchor_atid, mdr->ls);
+  if (mdr->more()->dst_reanchor_atid) 
+    mds->anchorclient->commit(mdr->more()->dst_reanchor_atid, mdr->ls);
 
   // bump popularity
   //if (srcdn->is_auth())
@@ -2970,12 +2972,12 @@ void Server::_rename_prepare_witness(MDRequest *mdr, int who, CDentry *srcdn, CD
   }
   
   // srcdn auth will verify our current witness list is sufficient
-  req->witnesses = mdr->witnessed;
+  req->witnesses = mdr->more()->witnessed;
 
   mds->send_message_mds(req, who, MDS_PORT_SERVER);
   
-  assert(mdr->waiting_on_slave.count(who) == 0);
-  mdr->waiting_on_slave.insert(who);
+  assert(mdr->more()->waiting_on_slave.count(who) == 0);
+  mdr->more()->waiting_on_slave.insert(who);
 }
 
 
@@ -2990,9 +2992,9 @@ void Server::_rename_prepare(MDRequest *mdr,
                    (srcdn->is_primary() || destdn->is_primary()));
 
   if (mdr->is_master()) {
-    mdr->pvmap[destdn->dir->inode] = predirty_dn_diri(mdr, destdn, metablob); 
+    mdr->more()->pvmap[destdn->dir->inode] = predirty_dn_diri(mdr, destdn, metablob); 
     if (destdn->dir != srcdn->dir)
-      mdr->pvmap[srcdn->dir->inode] = predirty_dn_diri(mdr, srcdn, metablob); 
+      mdr->more()->pvmap[srcdn->dir->inode] = predirty_dn_diri(mdr, srcdn, metablob); 
   }
 
   inode_t *ji = 0;     // journaled inode getting nlink--
@@ -3004,13 +3006,13 @@ void Server::_rename_prepare(MDRequest *mdr,
     // destdn -> primary
     metablob->add_dir_context(destdn->dir);
     if (destdn->is_auth())
-      ipv = mdr->pvmap[destdn] = destdn->pre_dirty(destdn->inode->inode.version);
+      ipv = mdr->more()->pvmap[destdn] = destdn->pre_dirty(destdn->inode->inode.version);
     ji = metablob->add_primary_dentry(destdn, true, destdn->inode); 
     
     // do src dentry
     metablob->add_dir_context(srcdn->dir);
     if (srcdn->is_auth())
-      mdr->pvmap[srcdn] = srcdn->pre_dirty();
+      mdr->more()->pvmap[srcdn] = srcdn->pre_dirty();
     metablob->add_null_dentry(srcdn, true);
 
   } else {
@@ -3022,7 +3024,7 @@ void Server::_rename_prepare(MDRequest *mdr,
       // link-- inode, move to stray dir.
       metablob->add_dir_context(straydn->dir);
       if (straydn->is_auth())
-       ipv = mdr->pvmap[straydn] = straydn->pre_dirty(destdn->inode->inode.version);
+       ipv = mdr->more()->pvmap[straydn] = straydn->pre_dirty(destdn->inode->inode.version);
       ji = metablob->add_primary_dentry(straydn, true, destdn->inode);
     } 
     else if (destdn->is_remote()) {
@@ -3030,7 +3032,7 @@ void Server::_rename_prepare(MDRequest *mdr,
       // nlink-- targeti
       metablob->add_dir_context(destdn->inode->get_parent_dir());
       if (destdn->inode->is_auth())
-       ipv = mdr->pvmap[destdn->inode] = destdn->inode->pre_dirty();
+       ipv = mdr->more()->pvmap[destdn->inode] = destdn->inode->pre_dirty();
       ji = metablob->add_primary_dentry(destdn->inode->parent, true, destdn->inode);  // update primary
       dout(10) << "remote targeti (nlink--) is " << *destdn->inode << dendl;
     }
@@ -3047,8 +3049,8 @@ void Server::_rename_prepare(MDRequest *mdr,
        if (srcdn->is_auth())
          siv = srcdn->inode->get_projected_version();
        else
-         siv = mdr->inode_import_v;
-       mdr->pvmap[destdn] = destdn->pre_dirty(siv+1);
+         siv = mdr->more()->inode_import_v;
+       mdr->more()->pvmap[destdn] = destdn->pre_dirty(siv+1);
       }
       metablob->add_primary_dentry(destdn, true, srcdn->inode); 
 
@@ -3056,14 +3058,14 @@ void Server::_rename_prepare(MDRequest *mdr,
       assert(srcdn->is_remote());
       dout(10) << "src is a remote dentry" << dendl;
       if (destdn->is_auth())
-       mdr->pvmap[destdn] = destdn->pre_dirty();
+       mdr->more()->pvmap[destdn] = destdn->pre_dirty();
       metablob->add_remote_dentry(destdn, true, srcdn->get_remote_ino()); 
     }
     
     // remove src dentry
     metablob->add_dir_context(srcdn->dir);
     if (srcdn->is_auth())
-      mdr->pvmap[srcdn] = srcdn->pre_dirty();
+      mdr->more()->pvmap[srcdn] = srcdn->pre_dirty();
     metablob->add_null_dentry(srcdn, true);
 
     // new subtree?
@@ -3087,17 +3089,17 @@ void Server::_rename_prepare(MDRequest *mdr,
   }
 
   // anchor updates?
-  if (mdr->src_reanchor_atid)
-    metablob->add_anchor_transaction(mdr->src_reanchor_atid);
-  if (mdr->dst_reanchor_atid)
-    metablob->add_anchor_transaction(mdr->dst_reanchor_atid);
+  if (mdr->more()->src_reanchor_atid)
+    metablob->add_anchor_transaction(mdr->more()->src_reanchor_atid);
+  if (mdr->more()->dst_reanchor_atid)
+    metablob->add_anchor_transaction(mdr->more()->dst_reanchor_atid);
 }
 
 
 void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDentry *straydn)
 {
   dout(10) << "_rename_apply " << *mdr << " " << *srcdn << " " << *destdn << dendl;
-  dout(10) << " pvs " << mdr->pvmap << dendl;
+  dout(10) << " pvs " << mdr->more()->pvmap << dendl;
 
   CInode *oldin = destdn->inode;
   
@@ -3107,9 +3109,9 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
 
   // dir mtimes
   if (mdr->is_master()) {
-    dirty_dn_diri(mdr, destdn, mdr->pvmap[destdn->dir->inode]);
+    dirty_dn_diri(mdr, destdn, mdr->more()->pvmap[destdn->dir->inode]);
     if (destdn->dir != srcdn->dir)
-      dirty_dn_diri(mdr, srcdn, mdr->pvmap[srcdn->dir->inode]);
+      dirty_dn_diri(mdr, srcdn, mdr->more()->pvmap[srcdn->dir->inode]);
   }
 
   if (linkmerge) {
@@ -3120,12 +3122,12 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
       destdn->inode->inode.nlink--;
       destdn->inode->inode.ctime = mdr->now;
       if (destdn->inode->is_auth())
-       destdn->inode->mark_dirty(mdr->pvmap[destdn], mdr->ls);
+       destdn->inode->mark_dirty(mdr->more()->pvmap[destdn], mdr->ls);
 
       // unlink srcdn
       srcdn->dir->unlink_inode(srcdn);
       if (srcdn->is_auth())
-       srcdn->mark_dirty(mdr->pvmap[srcdn], mdr->ls);
+       srcdn->mark_dirty(mdr->more()->pvmap[srcdn], mdr->ls);
     } else {
       dout(10) << "merging primary onto remote link" << dendl;
       assert(srcdn->is_primary());
@@ -3139,11 +3141,11 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
       destdn->inode->inode.nlink--;
       destdn->inode->inode.ctime = mdr->now;
       if (destdn->inode->is_auth())
-       destdn->inode->mark_dirty(mdr->pvmap[destdn], mdr->ls);
+       destdn->inode->mark_dirty(mdr->more()->pvmap[destdn], mdr->ls);
       
       // mark src dirty
       if (srcdn->is_auth())
-       srcdn->mark_dirty(mdr->pvmap[srcdn], mdr->ls);
+       srcdn->mark_dirty(mdr->more()->pvmap[srcdn], mdr->ls);
     }
   } 
   else {
@@ -3181,7 +3183,7 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
       destdn->dir->link_remote_inode(destdn, in->ino(), MODE_TO_DT(in->inode.mode));    
       destdn->link_remote(in);
       if (destdn->is_auth())
-       destdn->mark_dirty(mdr->pvmap[destdn], mdr->ls);
+       destdn->mark_dirty(mdr->more()->pvmap[destdn], mdr->ls);
     } else {
       // srcdn was primary.
       srcdn->dir->unlink_inode(srcdn);
@@ -3189,8 +3191,8 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
 
       // srcdn inode import?
       if (!srcdn->is_auth() && destdn->is_auth()) {
-       assert(mdr->inode_import.length() > 0);
-       bufferlist::iterator blp = mdr->inode_import.begin();
+       assert(mdr->more()->inode_import.length() > 0);
+       bufferlist::iterator blp = mdr->more()->inode_import.begin();
        map<int,entity_inst_t> imported_client_map;
        list<ScatterLock*> updated_scatterlocks;  // we clear_updated explicitly below
        ::_decode_simple(imported_client_map, blp);
@@ -3202,11 +3204,11 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen
        destdn->inode->dirlock.clear_updated();   
       }
       if (destdn->inode->is_auth())
-       destdn->inode->mark_dirty(mdr->pvmap[destdn], mdr->ls);
+       destdn->inode->mark_dirty(mdr->more()->pvmap[destdn], mdr->ls);
     }
 
     if (srcdn->is_auth())
-      srcdn->mark_dirty(mdr->pvmap[srcdn], mdr->ls);
+      srcdn->mark_dirty(mdr->more()->pvmap[srcdn], mdr->ls);
   }
 
   // update subtree map?
@@ -3299,8 +3301,8 @@ void Server::handle_slave_rename_prep(MDRequest *mdr)
   mdr->now = mdr->slave_request->now;
 
   // set up commit waiter (early, to clean up any freezing etc we do)
-  if (!mdr->slave_commit)
-    mdr->slave_commit = new C_MDS_SlaveRenameCommit(this, mdr, srcdn, destdn, straydn);
+  if (!mdr->more()->slave_commit)
+    mdr->more()->slave_commit = new C_MDS_SlaveRenameCommit(this, mdr, srcdn, destdn, straydn);
 
   // am i srcdn auth?
   if (srcdn->is_auth()) {
@@ -3454,6 +3456,50 @@ void Server::_commit_slave_rename(MDRequest *mdr, int r,
 
     // -- rollback in memory --
 
+    if (mdr->more()->was_link_merge) { 
+      // link merge
+      CInode *in = destdn->inode;
+      in->inode.nlink++;
+      if (mdr->more()->destdn_was_remote_inode) {
+       destdn->dir->unlink_inode(destdn);
+       srcdn->dir->link_primary_inode(srcdn, in);
+       destdn->dir->link_remote_inode(destdn, in->ino(),  MODE_TO_DT(in->inode.mode));
+      } else {
+       srcdn->dir->link_remote_inode(srcdn, in->ino(), MODE_TO_DT(in->inode.mode));
+      }
+    } else {
+      // normal
+
+      // revert srcdn
+      if (destdn->is_remote()) {
+       srcdn->dir->link_remote_inode(srcdn, destdn->inode->ino(), MODE_TO_DT(destdn->inode->inode.mode));
+       destdn->dir->unlink_inode(destdn);
+      } else {
+       // renamed a primary
+       CInode *in = destdn->inode;
+       destdn->dir->unlink_inode(destdn);
+       srcdn->dir->link_primary_inode(srcdn, in);
+      }
+      
+      // revert destdn
+      if (mdr->more()->destdn_was_remote_inode) {
+       destdn->dir->link_remote_inode(destdn, 
+                                      mdr->more()->destdn_was_remote_inode->ino(), 
+                                      MODE_TO_DT(mdr->more()->destdn_was_remote_inode->inode.mode));
+       mdr->more()->destdn_was_remote_inode->inode.nlink++;
+      } else if (straydn && straydn->inode) {
+       CInode *in = straydn->inode;
+       straydn->dir->unlink_inode(straydn);
+       destdn->dir->link_primary_inode(destdn, in);
+       straydn->dir->remove_dentry(straydn);
+      }
+    }
+
+    dout(-10) << "  srcdn back to " << *srcdn << dendl;
+    dout(-10) << "   srci back to " << *srcdn->inode << dendl;
+    dout(-10) << " destdn back to " << *destdn << dendl;
+    if (destdn->inode) dout(-10) << "  desti back to " << *destdn->inode << dendl;
+    
     // *** WRITE ME ***
     assert(0);
 
@@ -3472,33 +3518,33 @@ void Server::handle_slave_rename_prep_ack(MDRequest *mdr, MMDSSlaveRequest *ack)
   int from = ack->get_source().num();
 
   // note slave
-  mdr->slaves.insert(from);
+  mdr->more()->slaves.insert(from);
 
   // witnessed?  or add extra witnesses?
-  assert(mdr->witnessed.count(from) == 0);
+  assert(mdr->more()->witnessed.count(from) == 0);
   if (ack->witnesses.empty()) {
-    mdr->witnessed.insert(from);
+    mdr->more()->witnessed.insert(from);
   } else {
     dout(10) << " extra witnesses (srcdn replicas) are " << ack->witnesses << dendl;
-    mdr->extra_witnesses.swap(ack->witnesses);
-    mdr->extra_witnesses.erase(mds->get_nodeid());  // not me!
+    mdr->more()->extra_witnesses.swap(ack->witnesses);
+    mdr->more()->extra_witnesses.erase(mds->get_nodeid());  // not me!
   }
 
   // srci import?
   if (ack->inode_export.length()) {
     dout(10) << " got srci import" << dendl;
-    mdr->inode_import.claim(ack->inode_export);
-    mdr->inode_import_v = ack->inode_export_v;
+    mdr->more()->inode_import.claim(ack->inode_export);
+    mdr->more()->inode_import_v = ack->inode_export_v;
   }
 
   // remove from waiting list
-  assert(mdr->waiting_on_slave.count(from));
-  mdr->waiting_on_slave.erase(from);
+  assert(mdr->more()->waiting_on_slave.count(from));
+  mdr->more()->waiting_on_slave.erase(from);
 
-  if (mdr->waiting_on_slave.empty())
+  if (mdr->more()->waiting_on_slave.empty())
     dispatch_client_request(mdr);  // go again!
   else 
-    dout(10) << "still waiting on slaves " << mdr->waiting_on_slave << dendl;
+    dout(10) << "still waiting on slaves " << mdr->more()->waiting_on_slave << dendl;
 }
 
 
index 75f1cbfdbf9c4bcdc87fbc6955a9a755f07d45e3..356df039050c409a31b8b2ba58153f681115dbc7 100644 (file)
@@ -26,7 +26,7 @@
 
 # gethostbyname
 {
-   gethostbyname thing
+   gethostbyname on issdm
    Memcheck:Param
    socketcall.sendto(msg)
    fun:send
    fun:main
 }
 
+# gethostbyname
+
+{
+   gethostbyname on foil
+   Memcheck:Addr8
+   obj:/lib/ld-2.6.1.so
+   obj:/lib/ld-2.6.1.so
+   obj:/lib/ld-2.6.1.so
+   obj:/lib/ld-2.6.1.so
+   obj:/lib/ld-2.6.1.so
+   obj:/lib/ld-2.6.1.so
+   obj:/lib/ld-2.6.1.so
+   obj:/lib/libc-2.6.1.so
+   obj:/lib/ld-2.6.1.so
+   fun:__libc_dlopen_mode
+   fun:__nss_lookup_function
+   obj:/lib/libc-2.6.1.so
+}
+