}
}
-void CDir::assimilate_dirty_rstat_inodes()
+void CDir::assimilate_dirty_rstat_inodes(MutationRef& mut)
{
dout(10) << __func__ << dendl;
for (elist<CInode*>::iterator p = dirty_rstat_inodes.begin_use_current();
if (in->is_frozen())
continue;
- auto pi = in->project_inode();
+ mut->auth_pin(in);
+
+ auto pi = in->project_inode(mut);
pi.inode->version = in->pre_dirty();
- inode->mdcache->project_rstat_inode_to_frag(in, this, 0, 0, NULL);
+ inode->mdcache->project_rstat_inode_to_frag(mut, in, this, 0, 0, nullptr);
}
state_set(STATE_ASSIMRSTAT);
dout(10) << __func__ << " done" << dendl;
}
-void CDir::assimilate_dirty_rstat_inodes_finish(MutationRef& mut, EMetaBlob *blob)
+void CDir::assimilate_dirty_rstat_inodes_finish(EMetaBlob *blob)
{
if (!state_test(STATE_ASSIMRSTAT))
return;
CDentry *dn = in->get_projected_parent_dn();
- mut->auth_pin(in);
- mut->add_projected_inode(in);
-
in->clear_dirty_rstat();
blob->add_primary_dentry(dn, in, true);
}
// dirty/clean
-CDir::fnode_ptr CDir::project_fnode()
+CDir::fnode_ptr CDir::project_fnode(const MutationRef& mut)
{
ceph_assert(get_version() != 0);
+ if (mut && mut->is_projected(this))
+ return std::const_pointer_cast<fnode_t>(projected_fnode.back());
+
auto pf = allocate_fnode(*get_projected_fnode());
if (scrub_infop && scrub_infop->last_scrub_dirty) {
}
projected_fnode.emplace_back(pf);
+ if (mut)
+ mut->add_projected_node(this);
dout(10) << __func__ << " " << pf.get() << dendl;
return pf;
}
-void CDir::pop_and_dirty_projected_fnode(LogSegment *ls)
+void CDir::pop_and_dirty_projected_fnode(LogSegment *ls, const MutationRef& mut)
{
ceph_assert(!projected_fnode.empty());
auto pf = std::move(projected_fnode.front());
dout(15) << __func__ << " " << pf.get() << " v" << pf->version << dendl;
projected_fnode.pop_front();
+ if (mut)
+ mut->remove_projected_node(this);
reset_fnode(std::move(pf));
_mark_dirty(ls);
}
-
version_t CDir::pre_dirty(version_t min)
{
if (min > projected_version)
if (pv) {
ceph_assert(get_version() < pv);
ceph_assert(pv <= projected_version);
- ceph_assert(!projected_fnode.empty());
+ ceph_assert(!projected_fnode.empty() &&
+ pv <= projected_fnode.front()->version);
}
_mark_dirty(ls);
void resync_accounted_fragstat();
void resync_accounted_rstat();
- void assimilate_dirty_rstat_inodes();
- void assimilate_dirty_rstat_inodes_finish(MutationRef& mut, EMetaBlob *blob);
+ void assimilate_dirty_rstat_inodes(MutationRef& mut);
+ void assimilate_dirty_rstat_inodes_finish(EMetaBlob *blob);
void mark_exporting() {
state_set(CDir::STATE_EXPORTING);
return const_cast<fnode_t*>(projected_fnode.back().get());
}
- fnode_ptr project_fnode();
+ fnode_ptr project_fnode(const MutationRef& mut);
- void pop_and_dirty_projected_fnode(LogSegment *ls);
+ void pop_and_dirty_projected_fnode(LogSegment *ls, const MutationRef& mut);
bool is_projected() const { return !projected_fnode.empty(); }
version_t pre_dirty(version_t min=0);
void _mark_dirty(LogSegment *ls);
}
}
-CInode::projected_inode CInode::project_inode(bool xattr, bool snap)
+CInode::projected_inode CInode::project_inode(const MutationRef& mut,
+ bool xattr, bool snap)
{
+ if (mut && mut->is_projected(this)) {
+ ceph_assert(!xattr && !snap);
+ auto _inode = std::const_pointer_cast<mempool_inode>(projected_nodes.back().inode);
+ return projected_inode(std::move(_inode), xattr_map_ptr());
+ }
+
auto pi = allocate_inode(*get_projected_inode());
if (scrub_infop && scrub_infop->last_scrub_dirty) {
}
projected_nodes.emplace_back(pi, xattr ? px : ox , ps);
-
+ if (mut)
+ mut->add_projected_node(this);
dout(15) << __func__ << " " << pi->ino << dendl;
return projected_inode(std::move(pi), std::move(px), ps);
}
-void CInode::pop_and_dirty_projected_inode(LogSegment *ls)
+void CInode::pop_and_dirty_projected_inode(LogSegment *ls, const MutationRef& mut)
{
ceph_assert(!projected_nodes.empty());
auto front = std::move(projected_nodes.front());
dout(15) << __func__ << " v" << front.inode->version << dendl;
projected_nodes.pop_front();
+ if (mut)
+ mut->remove_projected_node(this);
bool pool_update = get_inode()->layout.pool_id != front.inode->layout.pool_id;
bool pin_update = get_inode()->export_pin != front.inode->export_pin;
MutationRef mut(new MutationImpl());
mut->ls = mdlog->get_current_segment();
- auto pf = dir->project_fnode();
+ auto pf = dir->project_fnode(mut);
std::string_view ename;
switch (lock->get_type()) {
if (!is_auth() && lock->get_state() == LOCK_MIX) {
dout(10) << __func__ << " try to assimilate dirty rstat on "
<< *dir << dendl;
- dir->assimilate_dirty_rstat_inodes();
+ dir->assimilate_dirty_rstat_inodes(mut);
}
break;
!is_auth() && lock->get_state() == LOCK_MIX) {
dout(10) << __func__ << " finish assimilating dirty rstat on "
<< *dir << dendl;
- dir->assimilate_dirty_rstat_inodes_finish(mut, &le->metablob);
+ dir->assimilate_dirty_rstat_inodes_finish(&le->metablob);
if (!(pf->rstat == pf->accounted_rstat)) {
if (!mut->is_wrlocked(&nestlock)) {
}
pf->version = dir->pre_dirty();
- mut->add_projected_fnode(dir);
mdlog->submit_entry(le, new C_Inode_FragUpdate(this, dir, mut));
} else {
* un-stale.
*/
/* for more info on scatterlocks, see comments by Locker::scatter_writebehind */
-void CInode::finish_scatter_gather_update(int type)
+void CInode::finish_scatter_gather_update(int type, MutationRef& mut)
{
LogChannelRef clog = mdcache->mds->clog;
}
CDir::fnode_const_ptr pf;
- if (update)
- pf = dir->project_fnode();
- else
+ if (update) {
+ mut->auth_pin(dir);
+ pf = dir->project_fnode(mut);
+ } else {
pf = dir->get_projected_fnode();
+ }
if (pf->accounted_fragstat.version == pi->dirstat.version - 1) {
dout(20) << fg << " fragstat " << pf->fragstat << dendl;
auto _pf = const_cast<fnode_t*>(pf.get());
_pf->accounted_fragstat = _pf->fragstat;
_pf->fragstat.version = _pf->accounted_fragstat.version = pi->dirstat.version;
+ _pf->version = dir->pre_dirty();
dout(10) << fg << " updated accounted_fragstat " << pf->fragstat << " on " << *dir << dendl;
}
}
CDir::fnode_const_ptr pf;
- if (update)
- pf = dir->project_fnode();
- else
+ if (update) {
+ mut->auth_pin(dir);
+ pf = dir->project_fnode(mut);
+ } else {
pf = dir->get_projected_fnode();
+ }
if (pf->accounted_rstat.version == pi->rstat.version-1) {
// only pull this frag's dirty rstat inodes into the frag if
// the frag is non-stale and updateable. if it's stale,
// that info will just get thrown out!
if (update)
- dir->assimilate_dirty_rstat_inodes();
+ dir->assimilate_dirty_rstat_inodes(mut);
dout(20) << fg << " rstat " << pf->rstat << dendl;
dout(20) << fg << " accounted_rstat " << pf->accounted_rstat << dendl;
if (update) {
auto _pf = const_cast<fnode_t*>(pf.get());
_pf->accounted_rstat = pf->rstat;
- dir->dirty_old_rstat.clear();
_pf->rstat.version = _pf->accounted_rstat.version = pi->rstat.version;
+ _pf->version = dir->pre_dirty();
+ dir->dirty_old_rstat.clear();
dir->check_rstats();
dout(10) << fg << " updated accounted_rstat " << pf->rstat << " on " << *dir << dendl;
}
}
}
-void CInode::finish_scatter_gather_update_accounted(int type, MutationRef& mut, EMetaBlob *metablob)
+void CInode::finish_scatter_gather_update_accounted(int type, EMetaBlob *metablob)
{
dout(10) << __func__ << " " << type << " on " << *this << dendl;
ceph_assert(is_auth());
continue; // nothing to do.
if (type == CEPH_LOCK_INEST)
- dir->assimilate_dirty_rstat_inodes_finish(mut, metablob);
+ dir->assimilate_dirty_rstat_inodes_finish(metablob);
dout(10) << " journaling updated frag accounted_ on " << *dir << dendl;
ceph_assert(dir->is_projected());
- auto pf = dir->_get_projected_fnode();
- pf->version = dir->pre_dirty();
- mut->add_projected_fnode(dir);
metablob->add_dir(dir, true);
- mut->auth_pin(dir);
}
}
sr_t* const snapnode;
projected_inode() = delete;
- explicit projected_inode(inode_ptr&& i, xattr_map_ptr&& x, sr_t *s) :
+ explicit projected_inode(inode_ptr&& i, xattr_map_ptr&& x, sr_t *s=nullptr) :
inode(std::move(i)), xattrs(std::move(x)), snapnode(s) {}
};
- projected_inode project_inode(bool xattr = false, bool snap = false);
+ projected_inode project_inode(const MutationRef& mut,
+ bool xattr = false, bool snap = false);
- void pop_and_dirty_projected_inode(LogSegment *ls);
+ void pop_and_dirty_projected_inode(LogSegment *ls, const MutationRef& mut);
version_t get_projected_version() const {
if (projected_nodes.empty())
void start_scatter(ScatterLock *lock);
void finish_scatter_update(ScatterLock *lock, CDir *dir,
version_t inode_version, version_t dir_accounted_version);
- void finish_scatter_gather_update(int type);
- void finish_scatter_gather_update_accounted(int type, MutationRef& mut, EMetaBlob *metablob);
+ void finish_scatter_gather_update(int type, MutationRef& mut);
+ void finish_scatter_gather_update_accounted(int type, EMetaBlob *metablob);
// -- snap --
void open_snaprealm(bool no_split=false);
client_t client, const ref_t<MClientCaps> &ack)
{
dout(10) << "file_update_finish on " << *in << dendl;
- in->pop_and_dirty_projected_inode(mut->ls);
mut->apply();
MutationRef mut(new MutationImpl());
mut->ls = mds->mdlog->get_current_segment();
- auto pi = in->project_inode();
+ auto pi = in->project_inode(mut);
pi.inode->version = in->pre_dirty();
if (update_max) {
CInode::mempool_inode *i;
if (oi) {
dout(10) << " writing into old inode" << dendl;
- auto pi = in->project_inode();
+ auto pi = in->project_inode(mut);
pi.inode->version = in->pre_dirty();
i = &oi->inode;
if (xattrs)
px = &oi->xattrs;
} else {
- auto pi = in->project_inode(xattrs);
+ auto pi = in->project_inode(mut, xattrs);
pi.inode->version = in->pre_dirty();
i = pi.inode.get();
if (xattrs)
m->xattrbl.length() &&
m->head.xattr_version > in->get_projected_inode()->xattr_version;
- auto pi = in->project_inode(xattr);
- pi.inode->version = in->pre_dirty();
-
MutationRef mut(new MutationImpl());
mut->ls = mds->mdlog->get_current_segment();
+ auto pi = in->project_inode(mut, xattr);
+ pi.inode->version = in->pre_dirty();
+
_update_cap_fields(in, dirty, m, pi.inode.get());
if (change_max) {
in->pre_cow_old_inode(); // avoid cow mayhem
- auto pi = in->project_inode();
+ auto pi = in->project_inode(mut);
pi.inode->version = in->pre_dirty();
- in->finish_scatter_gather_update(lock->get_type());
+ in->finish_scatter_gather_update(lock->get_type(), mut);
lock->start_flush();
EUpdate *le = new EUpdate(mds->mdlog, "scatter_writebehind");
mdcache->predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY);
mdcache->journal_dirty_inode(mut.get(), &le->metablob, in);
- in->finish_scatter_gather_update_accounted(lock->get_type(), mut, &le->metablob);
+ in->finish_scatter_gather_update_accounted(lock->get_type(), &le->metablob);
mds->mdlog->submit_entry(le, new C_Locker_ScatterWB(this, lock, mut));
}
{
CInode *in = static_cast<CInode*>(lock->get_parent());
dout(10) << "scatter_writebehind_finish on " << *lock << " on " << *in << dendl;
- in->pop_and_dirty_projected_inode(mut->ls);
+
+ mut->apply();
lock->finish_flush();
}
}
- mut->apply();
drop_locks(mut.get());
mut->cleanup();
}
}
-class C_MDC_SubtreeMergeWB : public MDCacheLogContext {
- CInode *in;
- MutationRef mut;
-public:
- C_MDC_SubtreeMergeWB(MDCache *mdc, CInode *i, MutationRef& m) : MDCacheLogContext(mdc), in(i), mut(m) {}
- void finish(int r) override {
- mdcache->subtree_merge_writebehind_finish(in, mut);
- }
-};
-
void MDCache::try_subtree_merge_at(CDir *dir, set<CInode*> *to_eval, bool adjust_pop)
{
dout(10) << "try_subtree_merge_at " << *dir << dendl;
}
}
-void MDCache::subtree_merge_writebehind_finish(CInode *in, MutationRef& mut)
-{
- dout(10) << "subtree_merge_writebehind_finish on " << in << dendl;
- in->pop_and_dirty_projected_inode(mut->ls);
-
- mut->apply();
- mds->locker->drop_locks(mut.get());
- mut->cleanup();
-
- in->auth_unpin(this);
-}
-
void MDCache::eval_subtree_root(CInode *diri)
{
// evaluate subtree inode filelock?
// nested ---------------------------------------------------------------
-void MDCache::project_rstat_inode_to_frag(CInode *cur, CDir *parent, snapid_t first,
+void MDCache::project_rstat_inode_to_frag(const MutationRef& mut,
+ CInode *cur, CDir *parent, snapid_t first,
int linkunlink, SnapRealm *prealm)
{
CDentry *parentdn = cur->get_projected_parent_dn();
}
// hacky
const CInode::mempool_inode *pi;
- if (update && cur->is_projected()) {
+ if (update && mut->is_projected(cur)) {
pi = cur->_get_projected_inode();
} else {
pi = cur->get_projected_inode().get();
// inode -> dirfrag
mut->auth_pin(parent);
- mut->add_projected_fnode(parent);
- auto pf = parent->project_fnode();
+ auto pf = parent->project_fnode(mut);
pf->version = parent->pre_dirty();
if (do_parent_mtime || linkunlink) {
parent->resync_accounted_rstat();
// now push inode rstats into frag
- project_rstat_inode_to_frag(cur, parent, first, linkunlink, prealm);
+ project_rstat_inode_to_frag(mut, cur, parent, first, linkunlink, prealm);
cur->clear_dirty_rstat();
}
// dirfrag -> diri
mut->auth_pin(pin);
- mut->add_projected_inode(pin);
lsi.push_front(pin);
pin->pre_cow_old_inode(); // avoid cow mayhem!
- auto pi = pin->project_inode();
+ auto pi = pin->project_inode(mut);
pi.inode->version = pin->pre_dirty();
// dirstat
s.erase(*s.rbegin());
dout(10) << " snaps in [" << in->first << "," << in->last << "] are " << s << dendl;
if (s.size() > 1) {
- CInode::mempool_inode pi = in->project_inode();
- pi->version = in->pre_dirty();
+ auto pi = in->project_inode(mut);
+ pi.inode.version = in->pre_dirty();
auto mut(std::make_shared<MutationImpl>());
mut->ls = mds->mdlog->get_current_segment();
void MDCache::_queued_file_recover_cow(CInode *in, MutationRef& mut)
{
- in->pop_and_dirty_projected_inode(mut->ls);
mut->apply();
mds->locker->drop_locks(mut.get());
mut->cleanup();
ceph_assert(p != ls->truncating_inodes.end());
ls->truncating_inodes.erase(p);
+ MutationRef mut(new MutationImpl());
+ mut->ls = mds->mdlog->get_current_segment();
+
// update
- auto pi = in->project_inode();
+ auto pi = in->project_inode(mut);
pi.inode->version = in->pre_dirty();
pi.inode->truncate_from = 0;
pi.inode->truncate_pending--;
- MutationRef mut(new MutationImpl());
- mut->ls = mds->mdlog->get_current_segment();
- mut->add_projected_inode(in);
-
EUpdate *le = new EUpdate(mds->mdlog, "truncate finish");
mds->mdlog->start_entry(le);
// dft lock
if (diri->is_auth()) {
// journal dirfragtree
- auto pi = diri->project_inode();
+ auto pi = diri->project_inode(mdr);
pi.inode->version = diri->pre_dirty();
predirty_journal_parents(mdr, &le->metablob, diri, 0, PREDIRTY_PRIMARY);
journal_dirty_inode(mdr.get(), &le->metablob, diri);
<< " on " << *diri << dendl;
mdr->mark_event("prepare logged");
- if (diri->is_auth())
- diri->pop_and_dirty_projected_inode(mdr->ls);
-
mdr->apply(); // mark scatterlock
// store resulting frags
}
if (diri_auth) {
- auto pi = diri->project_inode();
- mut->add_projected_inode(diri);
+ auto pi = diri->project_inode(mut);
pi.inode->version = diri->pre_dirty();
predirty_journal_parents(mut, &le->metablob, diri, 0, PREDIRTY_PRIMARY);
le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), diri, true);
return;
}
- auto _pf = dir->project_fnode();
+ auto _pf = dir->project_fnode(mdr);
_pf->version = dir->pre_dirty();
pf = _pf;
- mdr->add_projected_fnode(dir);
mdr->ls = mds->mdlog->get_current_segment();
EUpdate *le = new EUpdate(mds->mdlog, "repair_dirfrag");
return;
// project_snaprealm() upgrades snaprealm format
- auto pi = in->project_inode(false, true);
- mdr->add_projected_inode(in);
+ auto pi = in->project_inode(mdr, false, true);
pi.inode->version = in->pre_dirty();
mdr->ls = mds->mdlog->get_current_segment();
void map_dirfrag_set(const list<dirfrag_t>& dfs, set<CDir*>& result);
void try_subtree_merge(CDir *root);
void try_subtree_merge_at(CDir *root, set<CInode*> *to_eval, bool adjust_pop=true);
- void subtree_merge_writebehind_finish(CInode *in, MutationRef& mut);
void eval_subtree_root(CInode *diri);
CDir *get_subtree_root(CDir *dir);
CDir *get_projected_subtree_root(CDir *dir);
CInode **pcow_inode=0, CDentry::linkage_t *dnl=0);
void journal_dirty_inode(MutationImpl *mut, EMetaBlob *metablob, CInode *in, snapid_t follows=CEPH_NOSNAP);
- void project_rstat_inode_to_frag(CInode *cur, CDir *parent, snapid_t first,
+ void project_rstat_inode_to_frag(const MutationRef& mut,
+ CInode *cur, CDir *parent, snapid_t first,
int linkunlink, SnapRealm *prealm);
void _project_rstat_inode_to_frag(const CInode::mempool_inode* inode, snapid_t ofirst, snapid_t last,
CDir *parent, int linkunlink, bool update_inode);
#include "Mutation.h"
#include "ScatterLock.h"
+#include "CInode.h"
#include "CDir.h"
// MutationImpl
--num_remote_auth_pins;
}
-void MutationImpl::add_projected_inode(CInode *in)
-{
- projected_inodes.push_back(in);
-}
-
-void MutationImpl::pop_and_dirty_projected_inodes()
-{
- while (!projected_inodes.empty()) {
- CInode *in = projected_inodes.front();
- projected_inodes.pop_front();
- in->pop_and_dirty_projected_inode(ls);
- }
-}
-
-void MutationImpl::add_projected_fnode(CDir *dir)
-{
- projected_fnodes.push_back(dir);
-}
-
-void MutationImpl::pop_and_dirty_projected_fnodes()
-{
- for (const auto& dir : projected_fnodes) {
- dir->pop_and_dirty_projected_fnode(ls);
- }
- projected_fnodes.clear();
-}
-
void MutationImpl::add_updated_lock(ScatterLock *lock)
{
updated_locks.push_back(lock);
void MutationImpl::add_cow_dentry(CDentry *dn)
{
pin(dn);
- dirty_cow_dentries.push_back(pair<CDentry*,version_t>(dn, dn->get_projected_version()));
+ dirty_cow_dentries.emplace_back(dn, dn->get_projected_version());
}
void MutationImpl::apply()
{
- pop_and_dirty_projected_inodes();
-
- for (const auto& in : dirty_cow_inodes)
+ for (auto& obj : projected_nodes) {
+ if (CInode *in = dynamic_cast<CInode*>(obj))
+ in->pop_and_dirty_projected_inode(ls, nullptr);
+ }
+
+ for (const auto& in : dirty_cow_inodes) {
in->_mark_dirty(ls);
+ }
- for (const auto& [dn, v] : dirty_cow_dentries)
+ for (const auto& [dn, v] : dirty_cow_dentries) {
dn->mark_dirty(v, ls);
+ }
- pop_and_dirty_projected_fnodes();
+ for (auto& obj : projected_nodes) {
+ if (CDir *dir = dynamic_cast<CDir*>(obj))
+ dir->pop_and_dirty_projected_fnode(ls, nullptr);
+ }
for (const auto& lock : updated_locks) {
lock->mark_dirty();
}
+
+ projected_nodes.clear();
}
void MutationImpl::cleanup()
void set_remote_auth_pinned(MDSCacheObject* object, mds_rank_t from);
void _clear_remote_auth_pinned(ObjectState& stat);
- void add_projected_inode(CInode *in);
- void pop_and_dirty_projected_inodes();
- void add_projected_fnode(CDir *dir);
- void pop_and_dirty_projected_fnodes();
+ void add_projected_node(MDSCacheObject* obj) {
+ projected_nodes.insert(obj);
+ }
+ void remove_projected_node(MDSCacheObject* obj) {
+ projected_nodes.erase(obj);
+ }
+ bool is_projected(MDSCacheObject *obj) const {
+ return projected_nodes.count(obj);
+ }
void add_updated_lock(ScatterLock *lock);
void add_cow_inode(CInode *in);
void add_cow_dentry(CDentry *dn);
bool killed = false;
// for applying projected inode changes
- std::list<CInode*> projected_inodes;
- std::vector<CDir*> projected_fnodes;
+ std::set<MDSCacheObject*> projected_nodes;
std::list<ScatterLock*> updated_locks;
std::list<CInode*> dirty_cow_inodes;
ceph_assert(r == 0);
// apply
- in->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
MDSRank *mds = get_mds();
EUpdate *le = new EUpdate(mdlog, "setattr");
mdlog->start_entry(le);
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
if (mask & CEPH_SETATTR_UID)
pi.inode->uid = req->head.args.setattr.uid;
mdlog->start_entry(le);
// prepare
- auto pi = in->project_inode();
+ auto pi = in->project_inode(mdr);
pi.inode->version = in->pre_dirty();
pi.inode->mtime = pi.inode->ctime = mdr->get_op_stamp();
if (mdr->get_op_stamp() > pi.inode->rstat.rctime)
return;
// project update
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
pi.inode->layout = layout;
// add the old pool to the inode
pi.inode->add_old_pool(old_layout.pool_id);
if (!check_access(mdr, cur, access))
return;
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
pi.inode->layout = layout;
pi.inode->version = cur->pre_dirty();
if (check_layout_vxattr(mdr, rest, value, &layout) < 0)
return;
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
pi.inode->layout = layout;
mdr->no_early_reply = true;
pip = pi.inode.get();
if (!mds->locker->acquire_locks(mdr, lov))
return;
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
int64_t old_pool = pi.inode->layout.pool_id;
pi.inode->add_old_pool(old_pool);
pi.inode->layout = layout;
if (!xlock_policylock(mdr, cur, false, new_realm))
return;
- auto pi = cur->project_inode(false, new_realm);
+ auto pi = cur->project_inode(mdr, false, new_realm);
pi.inode->quota = quota;
if (new_realm) {
if (!xlock_policylock(mdr, cur))
return;
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
cur->set_export_pin(rank);
pip = pi.inode.get();
} else if (name == "ceph.dir.pin.random"sv) {
if (!xlock_policylock(mdr, cur))
return;
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
cur->setxattr_ephemeral_rand(val);
pip = pi.inode.get();
} else if (name == "ceph.dir.pin.distributed"sv) {
if (!xlock_policylock(mdr, cur))
return;
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
cur->setxattr_ephemeral_dist(val);
pip = pi.inode.get();
} else {
if (!mds->locker->acquire_locks(mdr, lov))
return;
- auto pi = cur->project_inode();
+ auto pi = cur->project_inode(mdr);
pi.inode->clear_layout();
pi.inode->version = cur->pre_dirty();
respond_to_request(mdr, -ENODATA);
}
-class C_MDS_inode_xattr_update_finish : public ServerLogContext {
- CInode *in;
-public:
-
- C_MDS_inode_xattr_update_finish(Server *s, MDRequestRef& r, CInode *i) :
- ServerLogContext(s, r), in(i) { }
- void finish(int r) override {
- ceph_assert(r == 0);
-
- // apply
- in->pop_and_dirty_projected_inode(mdr->ls);
-
- mdr->apply();
-
- get_mds()->balancer->hit_inode(in, META_POP_IWR);
-
- server->respond_to_request(mdr, 0);
- }
-};
-
void Server::handle_client_setxattr(MDRequestRef& mdr)
{
const cref_t<MClientRequest> &req = mdr->client_request;
dout(10) << "setxattr '" << name << "' len " << len << " on " << *cur << dendl;
// project update
- auto pi = cur->project_inode(true);
+ auto pi = cur->project_inode(mdr, true);
pi.inode->version = cur->pre_dirty();
pi.inode->ctime = mdr->get_op_stamp();
if (mdr->get_op_stamp() > pi.inode->rstat.rctime)
dout(10) << "removexattr '" << name << "' on " << *cur << dendl;
// project update
- auto pi = cur->project_inode(true);
+ auto pi = cur->project_inode(mdr, true);
auto &px = *pi.xattrs;
pi.inode->version = cur->pre_dirty();
pi.inode->ctime = mdr->get_op_stamp();
version_t tipv = targeti->pre_dirty();
// project inode update
- auto pi = targeti->project_inode();
+ auto pi = targeti->project_inode(mdr);
pi.inode->nlink++;
pi.inode->ctime = mdr->get_op_stamp();
if (mdr->get_op_stamp() > pi.inode->rstat.rctime)
dn->mark_dirty(dnpv, mdr->ls);
// target inode
- targeti->pop_and_dirty_projected_inode(mdr->ls);
-
mdr->apply();
MDRequestRef null_ref;
EPeerUpdate::OP_PREPARE, EPeerUpdate::LINK);
mdlog->start_entry(le);
- auto pi = dnl->get_inode()->project_inode();
+ auto pi = dnl->get_inode()->project_inode(mdr);
// update journaled target inode
bool inc;
ceph_assert(g_conf()->mds_kill_link_at != 6);
// update the target
- targeti->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
// hit pop
dout(10) << " target is " << *in << dendl;
ceph_assert(!in->is_projected()); // live peer request hold versionlock xlock.
- auto pi = in->project_inode();
+ auto pi = in->project_inode(mut);
pi.inode->version = in->pre_dirty();
- mut->add_projected_inode(in);
// parent dir rctime
CDir *parent = in->get_projected_parent_dn()->get_dir();
- auto pf = parent->project_fnode();
- mut->add_projected_fnode(parent);
+ auto pf = parent->project_fnode(mut);
pf->version = parent->pre_dirty();
if (pf->fragstat.mtime == pi.inode->ctime) {
pf->fragstat.mtime = rollback.old_dir_mtime;
// the unlinked dentry
dn->pre_dirty();
- auto pi = in->project_inode();
+ auto pi = in->project_inode(mdr);
{
std::string t;
dn->make_path_string(t, true);
pi.inode->update_backtrace();
le->metablob.add_primary_dentry(straydn, in, true, true);
} else {
- mdr->add_projected_inode(in);
// remote link. update remote inode.
mdcache->predirty_journal_parents(mdr, &le->metablob, in, dn->get_dir(), PREDIRTY_DIR, -1);
mdcache->predirty_journal_parents(mdr, &le->metablob, in, 0, PREDIRTY_PRIMARY);
// unlink main dentry
dn->get_dir()->unlink_inode(dn);
dn->pop_projected_linkage();
+ dn->mark_dirty(dnpv, mdr->ls);
// relink as stray? (i.e. was primary link?)
if (straydn) {
dout(20) << " straydn is " << *straydn << dendl;
straydn->pop_projected_linkage();
-
- strayin->pop_and_dirty_projected_inode(mdr->ls);
-
mdcache->touch_dentry_bottom(straydn);
}
- dn->mark_dirty(dnpv, mdr->ls);
mdr->apply();
mdcache->send_dentry_unlink(dn, straydn, mdr);
ceph_assert(straydn); // moving to straydn.
// link--, and move.
if (destdn->is_auth()) {
- auto pi= oldin->project_inode(); //project_snaprealm
+ auto pi= oldin->project_inode(mdr); //project_snaprealm
pi.inode->version = straydn->pre_dirty(pi.inode->version);
pi.inode->update_backtrace();
tpi = pi.inode.get();
} else if (destdnl->is_remote()) {
// nlink-- targeti
if (oldin->is_auth()) {
- auto pi = oldin->project_inode();
+ auto pi = oldin->project_inode(mdr);
pi.inode->version = oldin->pre_dirty();
tpi = pi.inode.get();
}
destdn->push_projected_linkage(srcdnl->get_remote_ino(), srcdnl->get_remote_d_type());
// srci
if (srci->is_auth()) {
- auto pi = srci->project_inode();
+ auto pi = srci->project_inode(mdr);
pi.inode->version = srci->pre_dirty();
spi = pi.inode.get();
}
} else {
dout(10) << " will merge remote onto primary link" << dendl;
if (destdn->is_auth()) {
- auto pi = oldin->project_inode();
+ auto pi = oldin->project_inode(mdr);
pi.inode->version = mdr->more()->pvmap[destdn] = destdn->pre_dirty(oldin->get_version());
spi = pi.inode.get();
}
dout(10) << " noting renamed dir open frags " << metablob->renamed_dir_frags << dendl;
}
}
- auto pi = srci->project_inode(); // project snaprealm if srcdnl->is_primary
+ auto pi = srci->project_inode(mdr); // project snaprealm if srcdnl->is_primary
// & srcdnl->snaprealm
pi.inode->version = mdr->more()->pvmap[destdn] = destdn->pre_dirty(oldpv);
pi.inode->update_backtrace();
// nlink-- targeti
if (destdn->is_auth())
- oldin->pop_and_dirty_projected_inode(mdr->ls);
+ oldin->pop_and_dirty_projected_inode(mdr->ls, mdr);
mdcache->touch_dentry_bottom(straydn); // drop dn as quickly as possible.
} else if (destdnl->is_remote()) {
destdn->get_dir()->unlink_inode(destdn, false);
if (oldin->is_auth()) {
- oldin->pop_and_dirty_projected_inode(mdr->ls);
+ oldin->pop_and_dirty_projected_inode(mdr->ls, mdr);
} else if (mdr->peer_request) {
if (mdr->peer_request->desti_snapbl.length() > 0) {
ceph_assert(oldin->snaprealm);
destdn->mark_dirty(mdr->more()->pvmap[destdn], mdr->ls);
// in
if (in->is_auth()) {
- in->pop_and_dirty_projected_inode(mdr->ls);
+ in->pop_and_dirty_projected_inode(mdr->ls, mdr);
} else if (mdr->peer_request) {
if (mdr->peer_request->srci_snapbl.length() > 0) {
ceph_assert(in->snaprealm);
}
} else {
dout(10) << "merging remote onto primary link" << dendl;
- oldin->pop_and_dirty_projected_inode(mdr->ls);
+ oldin->pop_and_dirty_projected_inode(mdr->ls, mdr);
}
} else { // primary
if (linkmerge) {
}
if (destdn->is_auth())
- in->pop_and_dirty_projected_inode(mdr->ls);
+ in->pop_and_dirty_projected_inode(mdr->ls, mdr);
}
// src
rename_rollback::drec &r, utime_t ctime,
bool isdir, const nest_info_t &rstat)
{
- auto pf = dir->project_fnode();
- mut->add_projected_fnode(dir);
+ auto pf = dir->project_fnode(mut);
pf->version = dir->pre_dirty();
if (isdir) {
bool projected;
CDir *pdir = in->get_projected_parent_dir();
if (pdir->authority().first == whoami) {
- auto pi = in->project_inode();
- mut->add_projected_inode(in);
+ auto pi = in->project_inode(mut);
pi.inode->version = in->pre_dirty();
if (pdir != srcdir) {
- auto pf = pdir->project_fnode();
- mut->add_projected_fnode(pdir);
+ auto pf = pdir->project_fnode(mut);
pf->version = pdir->pre_dirty();
}
if (pi.inode->ctime == rollback.ctime)
CInode::inode_ptr ti;
CDir *pdir = target->get_projected_parent_dir();
if (pdir->authority().first == whoami) {
- auto pi = target->project_inode();
- mut->add_projected_inode(target);
+ auto pi = target->project_inode(mut);
pi.inode->version = target->pre_dirty();
if (pdir != srcdir) {
- auto pf = pdir->project_fnode();
- mut->add_projected_fnode(pdir);
+ auto pf = pdir->project_fnode(mut);
pf->version = pdir->pre_dirty();
}
ti = pi.inode;
info.name = snapname;
info.stamp = mdr->get_op_stamp();
- auto pi = diri->project_inode(false, true);
+ auto pi = diri->project_inode(mdr, false, true);
pi.inode->ctime = info.stamp;
if (info.stamp > pi.inode->rstat.rctime)
pi.inode->rstat.rctime = info.stamp;
int op = (diri->snaprealm? CEPH_SNAP_OP_CREATE : CEPH_SNAP_OP_SPLIT);
- diri->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
mds->snapclient->commit(mdr->more()->stid, mdr->ls);
ceph_assert(mds->snapclient->get_cached_version() >= stid);
// journal
- auto pi = diri->project_inode(false, true);
+ auto pi = diri->project_inode(mdr, false, true);
pi.inode->version = diri->pre_dirty();
pi.inode->ctime = mdr->get_op_stamp();
if (mdr->get_op_stamp() > pi.inode->rstat.rctime)
snapid_t seq;
decode(seq, p);
- diri->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
mds->snapclient->commit(stid, mdr->ls);
ceph_assert(mds->snapclient->get_cached_version() >= stid);
// journal
- auto pi = diri->project_inode(false, true);
+ auto pi = diri->project_inode(mdr, false, true);
pi.inode->ctime = mdr->get_op_stamp();
if (mdr->get_op_stamp() > pi.inode->rstat.rctime)
pi.inode->rstat.rctime = mdr->get_op_stamp();
{
dout(10) << "_renamesnap_finish " << *mdr << " " << snapid << dendl;
- diri->pop_and_dirty_projected_inode(mdr->ls);
mdr->apply();
mds->snapclient->commit(mdr->more()->stid, mdr->ls);
MutationRef mut(new MutationImpl());
mut->ls = mds->mdlog->get_current_segment();
- auto pi = in->project_inode();
- mut->add_projected_inode(in);
+ auto pi = in->project_inode(mut);
pi.inode->size = 0;
pi.inode->max_size_ever = 0;
pi.inode->client_ranges.clear();
pi.inode->version = in->pre_dirty();
CDir *dir = dn->get_dir();
- auto pf = dir->project_fnode();
- mut->add_projected_fnode(dir);
+ auto pf = dir->project_fnode(mut);
pf->version = dir->pre_dirty();
EUpdate *le = new EUpdate(mds->mdlog, "purge_stray truncate");
// update dirfrag fragstat, rstat
CDir *dir = dn->get_dir();
- auto pf = dir->project_fnode();
- mut->add_projected_fnode(dir);
+ auto pf = dir->project_fnode(mut);
pf->version = dir->pre_dirty();
if (in->is_dir())
pf->fragstat.nsubdirs--;
state |= fullbit::STATE_EPHEMERAL_RANDOM;
}
- // make note of where this inode was last journaled
- in->last_journaled = event_seq;
- //cout << "journaling " << in->inode.ino << " at " << my_offset << std::endl;
-
const auto& pi = in->get_projected_inode();
+ ceph_assert(pi->version > 0);
+
if ((state & fullbit::STATE_DIRTY) && pi->is_backtrace_updated())
state |= fullbit::STATE_DIRTYPARENT;
lump.add_dfull(dn->get_name(), dn->first, dn->last, dn->get_projected_version(),
pi, in->dirfragtree, in->get_projected_xattrs(), in->symlink,
in->oldest_snap, snapbl, state, in->get_old_inodes());
+
+ // make note of where this inode was last journaled
+ in->last_journaled = event_seq;
+ //cout << "journaling " << in->inode.ino << " at " << my_offset << std::endl;
}
// convenience: primary or remote? figure it out.