- fix readdir vs fragment race by keeping a separate frag pos, and ignoring dentries below it
mds
+- on replay, but dirty scatter replicas on lists so that they get flushed? or does rejoin handle that?
- take some care with replayed client requests vs new requests
- linkage vs cdentry replicas and remote rename....
- move root inode into stray dir
if (!dirfragtree.is_leaf(*p)) {
dout(10) << " forcing frag " << *p << " to leaf (split|merge)" << dendl;
dirfragtree.force_to_leaf(*p);
- dirfragtreelock.set_updated();
+ dirfragtreelock.mark_dirty(); // ok bc we're auth and caller will handle
}
} else {
// replica. take the new tree, BUT make sure any open
dir->first = fgfirst;
if (!(fragstat == accounted_fragstat)) {
dout(10) << fg << " setting filelock updated flag" << dendl;
- filelock.set_updated();
+ filelock.mark_dirty(); // ok bc we're auth and caller will handle
}
} else {
if (dir && dir->is_auth()) {
dir->dirty_old_rstat.swap(dirty_old_rstat);
if (!(rstat == accounted_rstat) || dir->dirty_old_rstat.size()) {
dout(10) << fg << " setting nestlock updated flag" << dendl;
- nestlock.set_updated();
+ nestlock.mark_dirty(); // ok bc we're auth and caller will handle
}
} else {
if (dir && dir->is_auth()) {
lock->encode_locked_state(reply->get_data());
mds->send_message_mds(reply, auth);
next = LOCK_MIX_SYNC2;
+ ((ScatterLock *)lock)->start_flush();
}
break;
case LOCK_MIX_SYNC2:
+ ((ScatterLock *)lock)->finish_flush();
+
case LOCK_SYNC_MIX2:
// do nothing, we already acked
break;
// hack:
if (in->is_base()) {
dout(10) << "scatter_writebehind just clearing updated flag for base inode " << *in << dendl;
- lock->clear_updated();
+ lock->clear_dirty();
if (!lock->is_stable())
eval_gather(lock);
return;
pi->version = in->pre_dirty();
lock->get_parent()->finish_scatter_gather_update(lock->get_type());
- lock->clear_updated();
+ lock->start_flush();
EUpdate *le = new EUpdate(mds->mdlog, "scatter_writebehind");
mdcache->predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY, false);
dout(10) << "scatter_writebehind_finish on " << *lock << " on " << *in << dendl;
in->pop_and_dirty_projected_inode(mut->ls);
+ lock->finish_flush();
+
mut->apply();
drop_locks(mut);
mut->cleanup();
*/
void Locker::mark_updated_scatterlock(ScatterLock *lock)
{
- lock->set_updated();
+ lock->mark_dirty();
if (lock->xlistitem_updated.is_on_xlist()) {
dout(10) << "mark_updated_scatterlock " << *lock
<< " -- already on list since " << lock->update_stamp << dendl;
dnl->get_inode()->mark_clean();
// avoid touching scatterlocks for our subtree roots!
if (subtree_inodes.count(dnl->get_inode()) == 0) {
- dnl->get_inode()->filelock.clear_updated();
- dnl->get_inode()->nestlock.clear_updated();
- dnl->get_inode()->dirfragtreelock.clear_updated();
+ dnl->get_inode()->filelock.clear_dirty();
+ dnl->get_inode()->nestlock.clear_dirty();
+ dnl->get_inode()->dirfragtreelock.clear_dirty();
}
}
for (list<ScatterLock*>::iterator p = updated_locks.begin();
p != updated_locks.end();
p++)
- (*p)->set_updated();
+ (*p)->mark_dirty();
}
void cleanup() {
#include "SimpleLock.h"
class ScatterLock : public SimpleLock {
- bool updated;
+ bool dirty, flushing;
utime_t last_scatter;
public:
ScatterLock(MDSCacheObject *o, int t, int ws) :
SimpleLock(o, t, ws),
- updated(false),
+ dirty(false), flushing(false),
xlistitem_updated(this) {}
~ScatterLock() {
xlistitem_updated.remove_myself(); // FIXME this should happen sooner, i think...
}
- void set_updated() {
- if (!updated) {
- parent->get(MDSCacheObject::PIN_DIRTYSCATTERED);
- updated = true;
+ void mark_dirty() {
+ if (!dirty) {
+ if (!flushing)
+ parent->get(MDSCacheObject::PIN_DIRTYSCATTERED);
+ dirty = true;
}
}
- void clear_updated() {
- if (updated) {
+ void start_flush() {
+ flushing |= dirty;
+ dirty = false;
+ }
+ void finish_flush() {
+ flushing = false;
+ if (!dirty) {
parent->put(MDSCacheObject::PIN_DIRTYSCATTERED);
- updated = false;
parent->clear_dirty_scattered(type);
}
}
- bool is_updated() { return updated; }
+ void clear_dirty() {
+ start_flush();
+ finish_flush();
+ }
void set_last_scatter(utime_t t) { last_scatter = t; }
utime_t get_last_scatter() { return last_scatter; }
void print(ostream& out) {
out << "(";
_print(out);
- if (updated)
- out << " updated";
+ if (dirty)
+ out << " dirty";
+ if (flushing)
+ out << " flushing";
out << ")";
}
};
srcdn->authority().first,
mdr->ls,
mdr->more()->cap_imports, updated_scatterlocks);
- srcdnl->get_inode()->filelock.clear_updated();
- srcdnl->get_inode()->nestlock.clear_updated();
+ srcdnl->get_inode()->filelock.clear_dirty();
+ srcdnl->get_inode()->nestlock.clear_dirty();
// hack: force back to !auth and clean, temporarily
srcdnl->get_inode()->state_clear(CInode::STATE_AUTH);
if (lump.is_dirty()) {
dir->_mark_dirty(logseg);
- dir->get_inode()->filelock.set_updated();
+ dir->get_inode()->filelock.mark_dirty();
+ dir->get_inode()->nestlock.mark_dirty();
}
if (lump.is_new())
dir->mark_new(logseg);