projected_version = committing_version = committed_version = got_fnode.version;
if (fnode.rstat.version < inode->inode.rstat.version)
- inode->nestlock.set_stale();
+ inode->nestlock.set_and_apply_stale();
if (fnode.fragstat.version < inode->inode.dirstat.version)
- inode->filelock.set_stale();
+ inode->filelock.set_and_apply_stale();
}
// purge stale snaps?
inode_t *pi = inode->get_projected_inode();
if (fnode.fragstat.version != pi->dirstat.version) {
dout(10) << " got stale fragstat " << fnode.fragstat << " vs inode " << pi->dirstat << dendl;
- if (inode->filelock.get_state() == LOCK_MIX)
- inode->filelock.set_state(LOCK_MIX_STALE);
- else if (inode->filelock.get_state() != LOCK_MIX_STALE)
- inode->filelock.set_stale();
+ inode->filelock.set_and_apply_stale();
}
// stale rstat?
if (fnode.rstat.version != pi->rstat.version) {
dout(10) << " got stale rstat " << fnode.rstat << " vs inode " << pi->rstat << dendl;
- if (inode->nestlock.get_state() == LOCK_MIX)
- inode->nestlock.set_state(LOCK_MIX_STALE);
- else if (inode->nestlock.get_state() != LOCK_MIX_STALE)
- inode->nestlock.set_stale();
+ inode->nestlock.set_and_apply_stale();
}
}
::decode(linklock, p);
::decode(dirfragtreelock, p);
::decode(filelock, p);
+ filelock.apply_stale();
::decode(xattrlock, p);
::decode(snaplock, p);
::decode(nestlock, p);
+ nestlock.apply_stale();
::decode(flocklock, p);
::decode(policylock, p);
}
// ok
lock->decode_locked_state(m->get_data());
- if (!lock->is_stale())
- lock->set_state(LOCK_MIX);
- else {
+ if (!lock->is_stale()) {
dout(15) << "setting state to LOCK_MIX_STALE instead of LOCK_MIX" << dendl;
lock->set_state(LOCK_MIX_STALE);
- }
+ } else
+ lock->set_state(LOCK_MIX);
((ScatterLock *)lock)->finish_flush();
start_flush();
finish_flush();
}
-
+
+ /*
+ * "stale" means that at least one of our dirfrags has stale
+ * accounted_* scatter metadata on this inode. that means that any
+ * transition to MIX needs to implicitly go to MIX_STALE. also,
+ * MIX_STALE implies is_stale().
+ */
bool is_stale() const {
- return have_more() && _more->stale;
+ if (have_more() && _more->stale)
+ return true;
+ assert(state != LOCK_MIX_STALE); // invariant: LOCK_MIX_STALE => is_stale()
+ return false;
}
-
void set_stale() {
more()->stale = true;
}
-
void clear_stale() {
if (is_stale()) {
_more->stale = false;
try_clear_more();
}
}
+ void apply_stale() {
+ if (state == LOCK_MIX_STALE)
+ set_stale();
+ else if (is_stale() && state == LOCK_MIX)
+ state = LOCK_MIX_STALE;
+ }
+ void set_and_apply_stale() {
+ set_stale();
+ if (state == LOCK_MIX)
+ state = LOCK_MIX_STALE;
+ }
void set_last_scatter(utime_t t) { more()->last_scatter = t; }
utime_t get_last_scatter() {