out << " v" << in.get_version();
if (in.state_test(CInode::STATE_AMBIGUOUSAUTH)) out << " AMBIGAUTH";
+ if (in.state_test(CInode::STATE_NEEDSRECOVER)) out << " needsrecover";
+ if (in.state_test(CInode::STATE_RECOVERING)) out << " recovering";
if (in.is_freezing_inode()) out << " FREEZING=" << in.auth_pin_freeze_allowance;
if (in.is_frozen_inode()) out << " FROZEN";
static const int STATE_FROZEN = (1<<8);
static const int STATE_AMBIGUOUSAUTH = (1<<9);
static const int STATE_EXPORTINGCAPS = (1<<10);
+ static const int STATE_NEEDSRECOVER = (1<<11);
+ static const int STATE_RECOVERING = (1<<11);
// -- waiters --
//static const int WAIT_SLAVEAGREE = (1<<0);
off_t last_journaled; // log offset for the last time i was journaled
off_t last_open_journaled; // log offset for the last journaled EOpen
- // file recovery flag (when caps go stale)
- bool _needs_file_recovery;
- bool needs_file_recover() { return _needs_file_recovery; }
- void mark_needs_file_recover() { _needs_file_recovery = true; }
- void clear_needs_file_recover() { _needs_file_recovery = false; }
-
//bool hack_accessed;
//utime_t hack_load_stamp;
CInode(MDCache *c, bool auth=true) :
mdcache(c),
last_journaled(0), last_open_journaled(0),
- _needs_file_recovery(false),
//hack_accessed(true),
stickydir_ref(0),
parent(0), projected_parent(0),
if (issued) {
dout(10) << " revoking " << cap_string(issued) << " on " << *in << dendl;
cap->revoke();
- file_eval_gather(&in->filelock);
+ in->state_set(CInode::STATE_NEEDSRECOVER);
+ if (!in->filelock.is_stable())
+ file_eval_gather(&in->filelock);
if (in->is_auth()) {
if (in->filelock.is_stable())
file_eval(&in->filelock);
mdr->rdlocks.erase(lock);
mdr->locks.erase(lock);
- if (!lock->is_rdlocked())
- file_eval_gather(lock);
+ if (!lock->is_rdlocked()) {
+ if (!lock->is_stable())
+ file_eval_gather(lock);
+ else if (lock->get_parent()->is_auth())
+ file_eval(lock);
+ }
}
bool Locker::file_wrlock_start(FileLock *lock)
!lock->is_wrlocked() &&
lock->get_num_client_lease() == 0 &&
((issued & ~lock->caps_allowed()) == 0)) {
+
+ if (in->state_test(CInode::STATE_NEEDSRECOVER)) {
+ dout(7) << "file_eval_gather finished gather, but need to recover" << dendl;
+ mds->mdcache->queue_file_recover(in);
+ mds->mdcache->do_file_recover();
+ }
+ if (in->state_test(CInode::STATE_RECOVERING)) {
+ dout(7) << "file_eval_gather finished gather, but still recovering" << dendl;
+ return;
+ }
+
dout(7) << "file_eval_gather finished gather" << dendl;
switch (lock->get_state()) {
void MDCache::queue_file_recover(CInode *in)
{
dout(10) << "queue_file_recover " << *in << dendl;
- in->mark_needs_file_recover();
+ in->state_clear(CInode::STATE_NEEDSRECOVER);
+ in->state_set(CInode::STATE_RECOVERING);
in->auth_pin();
- assert(in->filelock.get_state() == LOCK_LOCK);
//in->filelock.get_xlock(0);
file_recover_queue.insert(in);
}
in->get_projected_inode()->size = in->inode.size;
file_recovering.erase(in);
- in->clear_needs_file_recover();
+ in->state_clear(CInode::STATE_RECOVERING);
in->auth_unpin();
//in->filelock.put_xlock();
CInode *in = cap->get_inode();
dout(20) << " killing capability " << cap_string(cap->issued()) << " on " << *in << dendl;
in->remove_client_cap(session->inst.name.num());
+ mds->locker->try_file_eval(&in->filelock);
}
while (!session->leases.empty()) {
ClientLease *r = session->leases.front();