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.
This commit is contained in:
Sage Weil 2010-03-29 16:26:54 -07:00
parent 65d3f3fd83
commit d5574993f4
3 changed files with 31 additions and 13 deletions

View File

@ -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++;

View File

@ -3889,8 +3889,11 @@ void MDCache::rejoin_gather_finish()
process_imported_caps();
process_reconnected_caps();
identify_files_to_recover();
vector<CInode*> 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<CInode*>& recover_q, vector<CInode*>& check_q)
{
dout(10) << "identify_files_to_recover" << dendl;
vector<CInode*> q; // put inodes in list first: queue_file_discover modifies inode_map
for (hash_map<vinodeno_t,CInode*>::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<CInode*>& recover_q, vector<CInode*>& check_q)
{
for (vector<CInode*>::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<CInode*>::iterator p = recover_q.begin(); p != recover_q.end(); p++) {
CInode *in = *p;
mds->locker->file_recover(&in->filelock);
}
for (vector<CInode*>::iterator p = q.begin(); p != q.end(); p++)
mds->locker->file_recover(&(*p)->filelock);
}
struct C_MDC_Recover : public Context {

View File

@ -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<CInode*>& recover_q, vector<CInode*>& check_q);
void start_files_to_recover(vector<CInode*>& recover_q, vector<CInode*>& check_q);
void do_file_recover();
void _recovered(CInode *in, int r, __u64 size, utime_t mtime);