// master. wrlock versionlock so we can pipeline inode updates to journal.
wrlocks.insert(&in->versionlock);
} else {
- // slave. exclusively lock the inode version (i.e. block other journal updates)
+ // slave. exclusively lock the inode version (i.e. block other journal updates).
+ // this makes rollback safe.
xlocks.insert(&in->versionlock);
sorted.insert(&in->versionlock);
}
return;
}
- // identify target inode
+ // identify target inode.
+ // use projected target; we'll rdlock the dentry to ensure it's correct.
CInode *targeti = mdcache->get_dentry_inode(targettrace[targettrace.size()-1], mdr, true);
if (!targeti)
return;
link_rollback rollback;
rollback.reqid = mdr->reqid;
rollback.ino = targeti->ino();
- rollback.old_ctime = targeti->inode.ctime; // we hold versionlock; no concorrent projections
+ rollback.old_ctime = targeti->inode.ctime; // we hold versionlock xlock; no concorrent projections
fnode_t *pf = targeti->get_parent_dn()->get_dir()->get_projected_fnode();
rollback.old_dir_mtime = pf->fragstat.mtime;
rollback.old_dir_rctime = pf->rstat.rctime;
CInode *in = mds->mdcache->get_inode(rollback.ino);
assert(in);
dout(10) << " target is " << *in << dendl;
- assert(!in->is_projected()); // live slave request hold versionlock.
+ assert(!in->is_projected()); // live slave request hold versionlock xlock.
inode_t *pi = in->project_inode();
pi->version = in->pre_dirty();