// -----auth-------- ---replica-------
#define LOCK_SYNC_ 1 // AR R . / C R . . . L R . / C R . . . L stat()
#define LOCK_LONER_SYNC -12 // A . . / C r . . . L * loner -> sync
-#define LOCK_MIXED_SYNC -13 // A . w / . R . . . L
+#define LOCK_MIXED_SYNC -13 // A . w / . R . . . L . w / . R . . . L
#define LOCK_LOCK_SYNC -14 // A . w / C . . . b L
#define LOCK_LOCK_ 2 // AR R W / C . . . B . . . / C . . . . . truncate()
-#define LOCK_SYNC_LOCK_ -3 // AR R . / C . . . . . . . / C . . . . .
+#define LOCK_SYNC_LOCK_ -3 // AR R . / C . . . . . r . / C . . . . .
#define LOCK_LONER_LOCK -4 // A . . / C . . . B . loner -> lock
-#define LOCK_MIXED_LOCK -5 // A . w / . . . . . .
+#define LOCK_MIXED_LOCK -5 // A . w / . . . . . . . w / . . . . . .
-#define LOCK_MIXED 6 // AR . W / . R W A . L . . / . R . . . L
-#define LOCK_SYNC_MIXED -7 // AR r . / . R . . . L . . / . R . . . L
+#define LOCK_MIXED 6 // AR . W / . R W A . L . W / . R . . . L
+#define LOCK_SYNC_MIXED -7 // AR r . / . R . . . L r . / . R . . . L
#define LOCK_LONER_MIXED -8 // A . . / . r w a . L * loner -> mixed
#define LOCK_LONER 9 // A . . / c r w a b L * (lock)
return (state == LOCK_LOCK ||
state == LOCK_MIXED);
else
- return (state == LOCK_LOCK ||
- state == LOCK_MIXED);
+ return (state == LOCK_MIXED);
}
void get_wrlock(bool force) {
assert(force || can_wrlock());
break;
// to sync
- case LOCK_LONER_SYNC:
case LOCK_MIXED_SYNC:
+ case LOCK_LONER_SYNC:
case LOCK_LOCK_SYNC:
lock->set_state(LOCK_SYNC);
in->loner_cap = -1;
lock->get_num_client_lease() == 0 &&
((other_issued & ~other_allowed)) == 0) {
switch (lock->get_state()) {
+ case LOCK_MIXED_SYNC:
+ if (!lock->is_wrlocked()) {
+ // reply
+ MLock *reply = new MLock(lock, LOCK_AC_SYNCACK, mds->get_nodeid());
+ lock->encode_locked_state(reply->get_data());
+ mds->send_message_mds(reply, in->authority().first);
+ lock->set_state(LOCK_LOCK); // this is sort of funky :/
+ }
+ break;
+
case LOCK_SYNC_MIXED:
{
lock->set_state(LOCK_MIXED);
}
if (lock->is_wrlocked())
gather++;
+ if (in->is_replicated() && lock->get_state() == LOCK_MIXED_SYNC) {
+ send_lock_message(lock, LOCK_AC_SYNC);
+ gather++;
+ }
if (in->state_test(CInode::STATE_NEEDSRECOVER)) {
mds->mdcache->queue_file_recover(in);
mds->mdcache->do_file_recover();
lock->set_state(LOCK_SYNC);
in->loner_cap = -1;
issue_caps(in);
+ lock->finish_waiters(FileLock::WAIT_RD|FileLock::WAIT_STABLE);
return true;
}
else {
lock->set_state(LOCK_LOCK);
in->loner_cap = -1;
+ lock->finish_waiters(FileLock::WAIT_XLOCK|FileLock::WAIT_WR|FileLock::WAIT_STABLE);
}
}
case LOCK_AC_SYNC:
assert(lock->get_state() == LOCK_LOCK ||
lock->get_state() == LOCK_MIXED);
+
+ if (lock->get_state() == LOCK_MIXED) {
+ // primary needs to gather up our changes
+ if (!lock->is_wrlocked()) {
+ // reply now
+ MLock *reply = new MLock(lock, LOCK_AC_SYNCACK, mds->get_nodeid());
+ lock->encode_locked_state(reply->get_data());
+ mds->send_message_mds(reply, from);
+ } else {
+ // gather
+ lock->set_state(LOCK_MIXED_SYNC);
+ }
+ } else {
+ // ok!
+ lock->decode_locked_state(m->get_data());
+ lock->set_state(LOCK_SYNC);
- lock->decode_locked_state(m->get_data());
- lock->set_state(LOCK_SYNC);
-
- // no need to reply.
-
- // waiters
- lock->get_rdlock();
- lock->finish_waiters(SimpleLock::WAIT_RD|SimpleLock::WAIT_STABLE);
- lock->put_rdlock();
- file_eval_gather(lock);
+ // no need to reply.
+
+ // waiters
+ lock->get_rdlock();
+ lock->finish_waiters(SimpleLock::WAIT_RD|SimpleLock::WAIT_STABLE);
+ lock->put_rdlock();
+ file_eval_gather(lock);
+ }
break;
case LOCK_AC_LOCK:
lock->set_state(LOCK_LOCK);
MLock *reply = new MLock(lock, LOCK_AC_LOCKACK, mds->get_nodeid());
+ if (lock->get_state() == LOCK_MIXED)
+ lock->encode_locked_state(reply->get_data());
mds->send_message_mds(reply, from);
}
break;
lock->get_state() == LOCK_SYNC_LONER);
assert(lock->is_gathering(from));
lock->remove_gather(from);
+
+ if (lock->get_state() == LOCK_MIXED_LOCK ||
+ lock->get_state() == LOCK_MIXED_LONER)
+ lock->decode_locked_state(m->get_data());
if (lock->is_gathering()) {
dout(7) << "handle_lock_inode_file " << *in << " from " << from
assert(lock->is_gathering(from));
lock->remove_gather(from);
- /* not used currently
- {
- // merge data (keep largest size, mtime, etc.)
- int off = 0;
- in->decode_merge_file_state(m->get_data(), off);
- }
- */
+ lock->decode_locked_state(m->get_data());
if (lock->is_gathering()) {
dout(7) << "handle_lock_inode_file " << *in << " from " << from