From d5574993f4d7fddac858a51ccaf2ce0475e3e367 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 29 Mar 2010 16:26:54 -0700 Subject: [PATCH] mds: start file recovery after sending rejoin ack The rejoin ack intializes replica lock states correctly; we can't send any lock messages before that. This fixes both the check max size call (which sends lock messages taking the wrlock) and the file_recover() call (which does the same). Instead, we make two lists, files to recover and those to fix up. The lock states for both are set to PRE_SCAN (LOCK on replica). After the rejoin acks go out, we either check_inode_max_size or file_recover. If file_recover someday grows another caller, this may need something a bit more sophisticated. --- src/mds/Locker.cc | 7 ++++--- src/mds/MDCache.cc | 33 ++++++++++++++++++++++++--------- src/mds/MDCache.h | 4 +++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index d3f33762df39e..f3dfcb0b3361f 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -3401,17 +3401,18 @@ void Locker::file_recover(ScatterLock *lock) assert(in->is_auth()); assert(lock->is_stable()); - int oldstate = lock->get_state(); - lock->set_state(LOCK_PRE_SCAN); + assert(lock->get_state() == LOCK_PRE_SCAN); // only called from MDCache::start_files_to_recover() int gather = 0; - if (in->is_replicated() && + /* + if (in->is_replicated() lock->get_sm()->states[oldstate].replica_state != LOCK_LOCK) { send_lock_message(lock, LOCK_AC_LOCK); lock->init_gather(); gather++; } + */ if (in->issued_caps_need_gather(lock)) { issue_caps(in); gather++; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 26401a594f663..01171b624ae01 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -3889,8 +3889,11 @@ void MDCache::rejoin_gather_finish() process_imported_caps(); process_reconnected_caps(); - identify_files_to_recover(); + + vector recover_q, check_q; + identify_files_to_recover(recover_q, check_q); rejoin_send_acks(); + start_files_to_recover(recover_q, check_q); // signal completion of fetches, rejoin_gather_finish, etc. assert(rejoin_ack_gather.count(mds->whoami)); @@ -4444,10 +4447,9 @@ void MDCache::unqueue_file_recover(CInode *in) * called after recovery to recover file sizes for previously opened (for write) * files. that is, those where max_size > size. */ -void MDCache::identify_files_to_recover() +void MDCache::identify_files_to_recover(vector& recover_q, vector& check_q) { dout(10) << "identify_files_to_recover" << dendl; - vector q; // put inodes in list first: queue_file_discover modifies inode_map for (hash_map::iterator p = inode_map.begin(); p != inode_map.end(); ++p) { @@ -4467,13 +4469,26 @@ void MDCache::identify_files_to_recover() } } - if (recover) - q.push_back(in); - else - mds->locker->check_inode_max_size(in); + if (recover) { + in->filelock.set_state(LOCK_PRE_SCAN); + recover_q.push_back(in); + } else { + check_q.push_back(in); + } + } +} + +void MDCache::start_files_to_recover(vector& recover_q, vector& check_q) +{ + for (vector::iterator p = check_q.begin(); p != check_q.end(); p++) { + CInode *in = *p; + in->filelock.set_state(LOCK_LOCK); + mds->locker->check_inode_max_size(in); + } + for (vector::iterator p = recover_q.begin(); p != recover_q.end(); p++) { + CInode *in = *p; + mds->locker->file_recover(&in->filelock); } - for (vector::iterator p = q.begin(); p != q.end(); p++) - mds->locker->file_recover(&(*p)->filelock); } struct C_MDC_Recover : public Context { diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 755c7116c9204..8deab3a870862 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -785,7 +785,9 @@ public: void unqueue_file_recover(CInode *in); void _queued_file_recover_cow(CInode *in, Mutation *mut); void _queue_file_recover(CInode *in); - void identify_files_to_recover(); + void identify_files_to_recover(vector& recover_q, vector& check_q); + void start_files_to_recover(vector& recover_q, vector& check_q); + void do_file_recover(); void _recovered(CInode *in, int r, __u64 size, utime_t mtime); -- 2.39.5