_mark_dirty(ls);
// mark dir too
- dir->mark_dirty(pv, ls);
+ dir->mark_dirty(ls, pv);
}
version_t pre_dirty(version_t min=0);
void _mark_dirty(LogSegment *ls);
- void mark_dirty(version_t projected_dirv, LogSegment *ls);
+ void mark_dirty(version_t pv, LogSegment *ls);
void mark_clean();
void mark_new();
int CDir::num_frozen_trees = 0;
int CDir::num_freezing_trees = 0;
+CDir::fnode_const_ptr CDir::empty_fnode = CDir::allocate_fnode();
+
class CDirContext : public MDSContext
{
protected:
if (dir.state_test(CDir::STATE_ASSIMRSTAT)) out << "|assimrstat";
// fragstat
- out << " " << dir.fnode.fragstat;
- if (!(dir.fnode.fragstat == dir.fnode.accounted_fragstat))
- out << "/" << dir.fnode.accounted_fragstat;
+ out << " " << dir.get_fnode()->fragstat;
+ if (!(dir.get_fnode()->fragstat == dir.get_fnode()->accounted_fragstat))
+ out << "/" << dir.get_fnode()->accounted_fragstat;
if (g_conf()->mds_debug_scatterstat && dir.is_projected()) {
- const fnode_t *pf = dir.get_projected_fnode();
+ const auto& pf = dir.get_projected_fnode();
out << "->" << pf->fragstat;
if (!(pf->fragstat == pf->accounted_fragstat))
out << "/" << pf->accounted_fragstat;
}
// rstat
- out << " " << dir.fnode.rstat;
- if (!(dir.fnode.rstat == dir.fnode.accounted_rstat))
- out << "/" << dir.fnode.accounted_rstat;
+ out << " " << dir.get_fnode()->rstat;
+ if (!(dir.get_fnode()->rstat == dir.get_fnode()->accounted_rstat))
+ out << "/" << dir.get_fnode()->accounted_rstat;
if (g_conf()->mds_debug_scatterstat && dir.is_projected()) {
- const fnode_t *pf = dir.get_projected_fnode();
+ const auto& pf = dir.get_projected_fnode();
out << "->" << pf->rstat;
if (!(pf->rstat == pf->accounted_rstat))
out << "/" << pf->accounted_rstat;
{
// auth
ceph_assert(in->is_dir());
- if (auth) state_set(STATE_AUTH);
+ if (auth)
+ state_set(STATE_AUTH);
}
/**
bool good = true;
// fragstat
- if(!frag_info.same_sums(fnode.fragstat)) {
+ if(!frag_info.same_sums(fnode->fragstat)) {
dout(1) << "mismatch between head items and fnode.fragstat! printing dentries" << dendl;
dout(1) << "get_num_head_items() = " << get_num_head_items()
- << "; fnode.fragstat.nfiles=" << fnode.fragstat.nfiles
- << " fnode.fragstat.nsubdirs=" << fnode.fragstat.nsubdirs << dendl;
+ << "; fnode.fragstat.nfiles=" << fnode->fragstat.nfiles
+ << " fnode.fragstat.nsubdirs=" << fnode->fragstat.nsubdirs << dendl;
good = false;
} else {
dout(20) << "get_num_head_items() = " << get_num_head_items()
- << "; fnode.fragstat.nfiles=" << fnode.fragstat.nfiles
- << " fnode.fragstat.nsubdirs=" << fnode.fragstat.nsubdirs << dendl;
+ << "; fnode.fragstat.nfiles=" << fnode->fragstat.nfiles
+ << " fnode.fragstat.nsubdirs=" << fnode->fragstat.nsubdirs << dendl;
}
// rstat
- if (!nest_info.same_sums(fnode.rstat)) {
+ if (!nest_info.same_sums(fnode->rstat)) {
dout(1) << "mismatch between child accounted_rstats and my rstats!" << dendl;
dout(1) << "total of child dentrys: " << nest_info << dendl;
- dout(1) << "my rstats: " << fnode.rstat << dendl;
+ dout(1) << "my rstats: " << fnode->rstat << dendl;
good = false;
} else {
dout(20) << "total of child dentrys: " << nest_info << dendl;
- dout(20) << "my rstats: " << fnode.rstat << dendl;
+ dout(20) << "my rstats: " << fnode->rstat << dendl;
}
if (!good) {
}
}
- ceph_assert(frag_info.nfiles == fnode.fragstat.nfiles);
- ceph_assert(frag_info.nsubdirs == fnode.fragstat.nsubdirs);
- ceph_assert(nest_info.rbytes == fnode.rstat.rbytes);
- ceph_assert(nest_info.rfiles == fnode.rstat.rfiles);
- ceph_assert(nest_info.rsubdirs == fnode.rstat.rsubdirs);
+ ceph_assert(frag_info.nfiles == fnode->fragstat.nfiles);
+ ceph_assert(frag_info.nsubdirs == fnode->fragstat.nsubdirs);
+ ceph_assert(nest_info.rbytes == fnode->rstat.rbytes);
+ ceph_assert(nest_info.rfiles == fnode->rstat.rfiles);
+ ceph_assert(nest_info.rsubdirs == fnode->rstat.rsubdirs);
}
}
dout(10) << "check_rstats complete on " << this << dendl;
} else if (dn->last == CEPH_NOSNAP) {
num_head_items++;
+ auto _fnode = _get_fnode();
+
if (dn->get_linkage()->is_primary()) {
CInode *in = dn->get_linkage()->get_inode();
const auto& pi = in->get_projected_inode();
if (in->is_dir()) {
- fnode.fragstat.nsubdirs++;
+ _fnode->fragstat.nsubdirs++;
if (in->item_pop_lru.is_on_list())
pop_lru_subdirs.push_back(&in->item_pop_lru);
} else {
- fnode.fragstat.nfiles++;
+ _fnode->fragstat.nfiles++;
}
- fnode.rstat.rbytes += pi->accounted_rstat.rbytes;
- fnode.rstat.rfiles += pi->accounted_rstat.rfiles;
- fnode.rstat.rsubdirs += pi->accounted_rstat.rsubdirs;
- fnode.rstat.rsnaps += pi->accounted_rstat.rsnaps;
- if (pi->accounted_rstat.rctime > fnode.rstat.rctime)
- fnode.rstat.rctime = pi->accounted_rstat.rctime;
+ _fnode->rstat.rbytes += pi->accounted_rstat.rbytes;
+ _fnode->rstat.rfiles += pi->accounted_rstat.rfiles;
+ _fnode->rstat.rsubdirs += pi->accounted_rstat.rsubdirs;
+ _fnode->rstat.rsnaps += pi->accounted_rstat.rsnaps;
+ if (pi->accounted_rstat.rctime > fnode->rstat.rctime)
+ _fnode->rstat.rctime = pi->accounted_rstat.rctime;
if (in->is_any_caps())
adjust_num_inodes_with_caps(1);
dirty_rstat_inodes.push_back(&in->dirty_rstat_item);
} else if (dn->get_linkage()->is_remote()) {
if (dn->get_linkage()->get_remote_d_type() == DT_DIR)
- fnode.fragstat.nsubdirs++;
+ _fnode->fragstat.nsubdirs++;
else
- fnode.fragstat.nfiles++;
+ _fnode->fragstat.nfiles++;
}
} else {
num_snap_items++;
nest_info_t rstatdiff;
frag_info_t fragstatdiff;
- if (fnode.accounted_rstat.version == rstat_version)
- rstatdiff.add_delta(fnode.accounted_rstat, fnode.rstat);
- if (fnode.accounted_fragstat.version == dirstat_version)
- fragstatdiff.add_delta(fnode.accounted_fragstat, fnode.fragstat);
+ if (fnode->accounted_rstat.version == rstat_version)
+ rstatdiff.add_delta(fnode->accounted_rstat, fnode->rstat);
+ if (fnode->accounted_fragstat.version == dirstat_version)
+ fragstatdiff.add_delta(fnode->accounted_fragstat, fnode->fragstat);
dout(10) << " rstatdiff " << rstatdiff << " fragstatdiff " << fragstatdiff << dendl;
map<string_snap_t, MDSContext::vec > dentry_waiters;
CDir *f = new CDir(inode, fg, cache, is_auth());
f->state_set(state & (MASK_STATE_FRAGMENT_KEPT | STATE_COMPLETE));
f->get_replicas() = get_replicas();
- f->set_version(get_version());
f->pop_me = pop_me;
f->pop_me.scale(fac);
// FIXME: handle dirty old rstat
// fix up new frag fragstats
- for (int i=0; i<n; i++) {
+ for (int i = 0; i < n; i++) {
CDir *f = subfrags[i];
- f->fnode.rstat.version = rstat_version;
- f->fnode.accounted_rstat = f->fnode.rstat;
- f->fnode.fragstat.version = dirstat_version;
- f->fnode.accounted_fragstat = f->fnode.fragstat;
- dout(10) << " rstat " << f->fnode.rstat << " fragstat " << f->fnode.fragstat
+ auto _fnode = f->_get_fnode();
+ _fnode->version = f->projected_version = get_version();
+ _fnode->rstat.version = rstat_version;
+ _fnode->accounted_rstat = _fnode->rstat;
+ _fnode->fragstat.version = dirstat_version;
+ _fnode->accounted_fragstat = _fnode->fragstat;
+ dout(10) << " rstat " << _fnode->rstat << " fragstat " << _fnode->fragstat
<< " on " << *f << dendl;
- }
- // give any outstanding frag stat differential to first frag
- dout(10) << " giving rstatdiff " << rstatdiff << " fragstatdiff" << fragstatdiff
- << " to " << *subfrags[0] << dendl;
- subfrags[0]->fnode.accounted_rstat.add(rstatdiff);
- subfrags[0]->fnode.accounted_fragstat.add(fragstatdiff);
+ if (i == 0) {
+ // give any outstanding frag stat differential to first frag
+ dout(10) << " giving rstatdiff " << rstatdiff << " fragstatdiff" << fragstatdiff
+ << " to " << *subfrags[0] << dendl;
+ _fnode->accounted_rstat.add(rstatdiff);
+ _fnode->accounted_fragstat.add(fragstatdiff);
+ }
+ }
finish_old_fragment(waiters, replay);
}
prepare_new_fragment(replay);
+ auto _fnode = _get_fnode();
+
nest_info_t rstatdiff;
frag_info_t fragstatdiff;
bool touched_mtime, touched_chattr;
dout(10) << " subfrag " << dir->get_frag() << " " << *dir << dendl;
ceph_assert(!dir->is_auth() || dir->is_complete() || replay);
- if (dir->fnode.accounted_rstat.version == rstat_version)
- rstatdiff.add_delta(dir->fnode.accounted_rstat, dir->fnode.rstat);
- if (dir->fnode.accounted_fragstat.version == dirstat_version)
- fragstatdiff.add_delta(dir->fnode.accounted_fragstat, dir->fnode.fragstat,
+ if (dir->get_fnode()->accounted_rstat.version == rstat_version)
+ rstatdiff.add_delta(dir->get_fnode()->accounted_rstat, dir->get_fnode()->rstat);
+ if (dir->get_fnode()->accounted_fragstat.version == dirstat_version)
+ fragstatdiff.add_delta(dir->get_fnode()->accounted_fragstat, dir->get_fnode()->fragstat,
&touched_mtime, &touched_chattr);
dir->prepare_old_fragment(dentry_waiters, replay);
}
// merge version
- if (dir->get_version() > get_version())
- set_version(dir->get_version());
+ if (dir->get_version() > _fnode->version)
+ _fnode->version = projected_version = dir->get_version();
// merge state
state_set(dir->get_state() & MASK_STATE_FRAGMENT_KEPT);
mark_complete();
// FIXME: merge dirty old rstat
- fnode.rstat.version = rstat_version;
- fnode.accounted_rstat = fnode.rstat;
- fnode.accounted_rstat.add(rstatdiff);
+ _fnode->rstat.version = rstat_version;
+ _fnode->accounted_rstat = _fnode->rstat;
+ _fnode->accounted_rstat.add(rstatdiff);
- fnode.fragstat.version = dirstat_version;
- fnode.accounted_fragstat = fnode.fragstat;
- fnode.accounted_fragstat.add(fragstatdiff);
+ _fnode->fragstat.version = dirstat_version;
+ _fnode->accounted_fragstat = _fnode->fragstat;
+ _fnode->accounted_fragstat.add(fragstatdiff);
init_fragment_pins();
}
void CDir::resync_accounted_fragstat()
{
- fnode_t *pf = get_projected_fnode();
+ auto pf = _get_projected_fnode();
const auto& pi = inode->get_projected_inode();
if (pf->accounted_fragstat.version != pi->dirstat.version) {
*/
void CDir::resync_accounted_rstat()
{
- fnode_t *pf = get_projected_fnode();
+ auto pf = _get_projected_fnode();
const auto& pi = inode->get_projected_inode();
if (pf->accounted_rstat.version != pi->rstat.version) {
// dirty/clean
-fnode_t *CDir::project_fnode()
+CDir::fnode_ptr CDir::project_fnode()
{
ceph_assert(get_version() != 0);
- auto &p = projected_fnode.emplace_back(*get_projected_fnode());
+
+ auto pf = allocate_fnode(*get_projected_fnode());
if (scrub_infop && scrub_infop->last_scrub_dirty) {
- p.localized_scrub_stamp = scrub_infop->last_local.time;
- p.localized_scrub_version = scrub_infop->last_local.version;
- p.recursive_scrub_stamp = scrub_infop->last_recursive.time;
- p.recursive_scrub_version = scrub_infop->last_recursive.version;
+ pf->localized_scrub_stamp = scrub_infop->last_local.time;
+ pf->localized_scrub_version = scrub_infop->last_local.version;
+ pf->recursive_scrub_stamp = scrub_infop->last_recursive.time;
+ pf->recursive_scrub_version = scrub_infop->last_recursive.version;
scrub_infop->last_scrub_dirty = false;
scrub_maybe_delete_info();
}
- dout(10) << __func__ << " " << &p << dendl;
- return &p;
+ projected_fnode.emplace_back(pf);
+ dout(10) << __func__ << " " << pf.get() << dendl;
+ return pf;
}
void CDir::pop_and_dirty_projected_fnode(LogSegment *ls)
{
ceph_assert(!projected_fnode.empty());
- auto &front = projected_fnode.front();
- dout(15) << __func__ << " " << &front << " v" << front.version << dendl;
- fnode = front;
- _mark_dirty(ls);
+ auto pf = std::move(projected_fnode.front());
+ dout(15) << __func__ << " " << pf.get() << " v" << pf->version << dendl;
+
projected_fnode.pop_front();
+
+ reset_fnode(std::move(pf));
+ _mark_dirty(ls);
}
return projected_version;
}
-void CDir::mark_dirty(version_t pv, LogSegment *ls)
+void CDir::mark_dirty(LogSegment *ls, version_t pv)
{
- ceph_assert(get_version() < pv);
- ceph_assert(pv <= projected_version);
- fnode.version = pv;
+ ceph_assert(is_auth());
+
+ if (pv) {
+ ceph_assert(get_version() < pv);
+ ceph_assert(pv <= projected_version);
+ ceph_assert(!projected_fnode.empty());
+ }
+
_mark_dirty(ls);
}
if (is_dirty() || projected_version > get_version())
return; // noop if it is already dirty or will be dirty
- version_t pv = pre_dirty();
- mark_dirty(pv, cache->mds->mdlog->get_current_segment());
+ auto _fnode = allocate_fnode(*get_fnode());
+ _fnode->version = pre_dirty();
+ reset_fnode(std::move(_fnode));
+ mark_dirty(cache->mds->mdlog->get_current_segment());
}
void CDir::mark_complete() {
dout(7) << "fetch dirfrag for unlinked directory, mark complete" << dendl;
if (get_version() == 0) {
ceph_assert(inode->is_auth());
- set_version(1);
+ auto _fnode = allocate_fnode();
+ _fnode->version = 1;
+ reset_fnode(std::move(_fnode));
if (state_test(STATE_REJOINUNDEF)) {
ceph_assert(cache->mds->is_rejoin());
if (get_version() == 0) {
ceph_assert(!is_projected());
ceph_assert(!state_test(STATE_COMMITTING));
- fnode = got_fnode;
- projected_version = committing_version = committed_version = got_fnode.version;
+ auto _fnode = allocate_fnode(got_fnode);
+ reset_fnode(std::move(_fnode));
+ projected_version = committing_version = committed_version = get_version();
if (state_test(STATE_REJOINUNDEF)) {
ceph_assert(cache->mds->is_rejoin());
SnapRealm *realm = inode->find_snaprealm();
if (!realm->have_past_parents_open()) {
dout(10) << " no snap purge, one or more past parents NOT open" << dendl;
- } else if (fnode.snap_purged_thru < realm->get_last_destroyed()) {
+ } else if (fnode->snap_purged_thru < realm->get_last_destroyed()) {
snaps = &realm->get_snaps();
- dout(10) << " snap_purged_thru " << fnode.snap_purged_thru
+ dout(10) << " snap_purged_thru " << fnode->snap_purged_thru
<< " < " << realm->get_last_destroyed()
<< ", snap purge based on " << *snaps << dendl;
if (get_num_snap_items() == 0) {
- fnode.snap_purged_thru = realm->get_last_destroyed();
+ const_cast<snapid_t&>(fnode->snap_purged_thru) = realm->get_last_destroyed();
force_dirty = true;
}
}
}
if (complete) {
- if (get_version() == 0)
- set_version(1);
+ if (get_version() == 0) {
+ auto _fnode = allocate_fnode();
+ _fnode->version = 1;
+ reset_fnode(std::move(_fnode));
+ }
state_set(STATE_BADFRAG);
mark_complete();
SnapRealm *realm = inode->find_snaprealm();
if (!realm->have_past_parents_open()) {
dout(10) << " no snap purge, one or more past parents NOT open" << dendl;
- } else if (fnode.snap_purged_thru < realm->get_last_destroyed()) {
+ } else if (fnode->snap_purged_thru < realm->get_last_destroyed()) {
snaps = &realm->get_snaps();
- dout(10) << " snap_purged_thru " << fnode.snap_purged_thru
+ dout(10) << " snap_purged_thru " << fnode->snap_purged_thru
<< " < " << realm->get_last_destroyed()
<< ", snap purge based on " << *snaps << dendl;
// fnode.snap_purged_thru = realm->get_last_destroyed();
* off last, we cannot get our header into an incorrect state.
*/
bufferlist header;
- encode(fnode, header);
+ encode(*fnode, header);
op.omap_set_header(header);
if (!to_set.empty())
ENCODE_START(1, 1, bl);
ceph_assert(!is_projected());
encode(first, bl);
- encode(fnode, bl);
+ encode(*fnode, bl);
encode(dirty_old_rstat, bl);
encode(committed_version, bl);
{
DECODE_START(1, blp);
decode(first, blp);
- decode(fnode, blp);
+ {
+ auto _fnode = allocate_fnode();
+ decode(*_fnode, blp);
+ reset_fnode(std::move(_fnode));
+ }
+ update_projected_version();
+
decode(dirty_old_rstat, blp);
- projected_version = fnode.version;
decode(committed_version, blp);
committing_version = committed_version;
// did we import some dirty scatterlock data?
if (dirty_old_rstat.size() ||
- !(fnode.rstat == fnode.accounted_rstat)) {
+ !(fnode->rstat == fnode->accounted_rstat)) {
cache->mds->locker->mark_updated_scatterlock(&inode->nestlock);
ls->dirty_dirfrag_nest.push_back(&inode->item_dirty_dirfrag_nest);
}
- if (!(fnode.fragstat == fnode.accounted_fragstat)) {
+ if (!(fnode->fragstat == fnode->accounted_fragstat)) {
cache->mds->locker->mark_updated_scatterlock(&inode->filelock);
ls->dirty_dirfrag_dir.push_back(&inode->item_dirty_dirfrag_dir);
}
}
}
- if (c.nsubdirs != fnode.fragstat.nsubdirs ||
- c.nfiles != fnode.fragstat.nfiles) {
- dout(0) << "verify_fragstat failed " << fnode.fragstat << " on " << *this << dendl;
+ if (c.nsubdirs != fnode->fragstat.nsubdirs ||
+ c.nfiles != fnode->fragstat.nfiles) {
+ dout(0) << "verify_fragstat failed " << fnode->fragstat << " on " << *this << dendl;
dout(0) << " i count " << c << dendl;
ceph_abort();
} else {
- dout(0) << "verify_fragstat ok " << fnode.fragstat << " on " << *this << dendl;
+ dout(0) << "verify_fragstat ok " << fnode->fragstat << " on " << *this << dendl;
}
}
#endif
// break out of const-land to set up implicit initial state
CDir *me = const_cast<CDir*>(this);
- fnode_t *fn = me->get_projected_fnode();
+ const auto& pf = me->get_projected_fnode();
std::unique_ptr<scrub_info_t> si(new scrub_info_t());
si->last_recursive.version = si->recursive_start.version =
- fn->recursive_scrub_version;
+ pf->recursive_scrub_version;
si->last_recursive.time = si->recursive_start.time =
- fn->recursive_scrub_stamp;
+ pf->recursive_scrub_stamp;
- si->last_local.version = fn->localized_scrub_version;
- si->last_local.time = fn->localized_scrub_stamp;
+ si->last_local.version = pf->localized_scrub_version;
+ si->last_local.time = pf->localized_scrub_stamp;
me->scrub_infop.swap(si);
}
typedef mempool::mds_co::map<dentry_key_t, CDentry*> dentry_key_map;
typedef mempool::mds_co::set<dentry_key_t> dentry_key_set;
+ using fnode_ptr = std::shared_ptr<fnode_t>;
+ using fnode_const_ptr = std::shared_ptr<const fnode_t>;
+
+ template <typename ...Args>
+ static fnode_ptr allocate_fnode(Args && ...args) {
+ static mempool::mds_co::pool_allocator<fnode_t> allocator;
+ return std::allocate_shared<fnode_t>(allocator, std::forward<Args>(args)...);
+ }
+
// -- freezing --
struct freeze_tree_state_t {
CDir *dir; // freezing/frozen tree root
inode->num_exporting_dirs--;
}
- version_t get_version() const { return fnode.version; }
- void set_version(version_t v) {
+ version_t get_version() const { return fnode->version; }
+ void update_projected_version() {
ceph_assert(projected_fnode.empty());
- projected_version = fnode.version = v;
+ projected_version = fnode->version;
}
version_t get_projected_version() const { return projected_version; }
- const fnode_t *get_projected_fnode() const {
- if (projected_fnode.empty())
- return &fnode;
- else
- return &projected_fnode.back();
+ void reset_fnode(fnode_const_ptr&& ptr) {
+ fnode = std::move(ptr);
+ }
+
+ const fnode_const_ptr& get_fnode() const {
+ return fnode;
}
- fnode_t *get_projected_fnode() {
+ // only used for updating newly allocated CDir
+ fnode_t* _get_fnode() {
+ if (fnode == empty_fnode)
+ reset_fnode(allocate_fnode());
+ return const_cast<fnode_t*>(fnode.get());
+ }
+
+ const fnode_const_ptr& get_projected_fnode() const {
if (projected_fnode.empty())
- return &fnode;
+ return fnode;
else
- return &projected_fnode.back();
+ return projected_fnode.back();
+ }
+
+ // fnode should have already been projected in caller's context
+ fnode_t* _get_projected_fnode() {
+ ceph_assert(!projected_fnode.empty());
+ return const_cast<fnode_t*>(projected_fnode.back().get());
}
- fnode_t *project_fnode();
+
+ fnode_ptr project_fnode();
void pop_and_dirty_projected_fnode(LogSegment *ls);
bool is_projected() const { return !projected_fnode.empty(); }
get(PIN_DIRTY);
}
}
- void mark_dirty(version_t pv, LogSegment *ls);
+ void mark_dirty(LogSegment *ls, version_t pv=0);
void mark_clean();
bool is_new() { return item_new.is_on_list(); }
void _encode_base(ceph::buffer::list& bl) {
ENCODE_START(1, 1, bl);
encode(first, bl);
- encode(fnode, bl);
+ encode(*fnode, bl);
encode(dir_rep, bl);
encode(dir_rep_by, bl);
ENCODE_FINISH(bl);
void _decode_base(ceph::buffer::list::const_iterator& p) {
DECODE_START(1, p);
decode(first, p);
- decode(fnode, p);
+ {
+ auto _fnode = allocate_fnode();
+ decode(*_fnode, p);
+ reset_fnode(std::move(_fnode));
+ }
decode(dir_rep, p);
decode(dir_rep_by, p);
DECODE_FINISH(p);
CInode *inode; // my inode
frag_t frag; // my frag
- fnode_t fnode;
snapid_t first = 2;
mempool::mds_co::compact_map<snapid_t,old_rstat_t> dirty_old_rstat; // [value.first,key]
void _encode_dentry(CDentry *dn, ceph::buffer::list& bl, const std::set<snapid_t> *snaps);
void _committed(int r, version_t v);
+ static fnode_const_ptr empty_fnode;
+ // fnode is a pointer to constant fnode_t, the constant fnode_t can be shared
+ // by CDir and log events. To update fnode, read-copy-update should be used.
+
+ fnode_const_ptr fnode = empty_fnode;
+
version_t projected_version = 0;
- mempool::mds_co::list<fnode_t> projected_fnode;
+ mempool::mds_co::list<fnode_const_ptr> projected_fnode;
std::unique_ptr<scrub_info_t> scrub_infop;
frag_t fg = p.first;
CDir *dir = p.second;
if (is_auth() || dir->is_auth()) {
- fnode_t *pf = dir->get_projected_fnode();
+ const auto& pf = dir->get_projected_fnode();
dout(15) << fg << " " << *dir << dendl;
dout(20) << fg << " fragstat " << pf->fragstat << dendl;
dout(20) << fg << " accounted_fragstat " << pf->accounted_fragstat << dendl;
dout(10) << fg << " first " << dir->first << " -> " << fgfirst
<< " on " << *dir << dendl;
dir->first = fgfirst;
- dir->fnode.fragstat = fragstat;
- dir->fnode.accounted_fragstat = accounted_fragstat;
+ auto _fnode = CDir::allocate_fnode(*dir->get_fnode());
+ _fnode->fragstat = fragstat;
+ _fnode->accounted_fragstat = accounted_fragstat;
+ dir->reset_fnode(std::move(_fnode));
if (!(fragstat == accounted_fragstat)) {
dout(10) << fg << " setting filelock updated flag" << dendl;
filelock.mark_dirty(); // ok bc we're auth and caller will handle
dout(10) << fg << " first " << dir->first << " -> " << fgfirst
<< " on " << *dir << dendl;
dir->first = fgfirst;
- fnode_t *pf = dir->get_projected_fnode();
+ const auto& pf = dir->get_projected_fnode();
finish_scatter_update(&filelock, dir,
_inode->dirstat.version, pf->accounted_fragstat.version);
}
frag_t fg = p.first;
CDir *dir = p.second;
if (is_auth() || dir->is_auth()) {
- fnode_t *pf = dir->get_projected_fnode();
+ const auto& pf = dir->get_projected_fnode();
dout(10) << __func__ << " " << fg << " dir " << *dir << dendl;
dout(10) << __func__ << " " << fg << " rstat " << pf->rstat << dendl;
dout(10) << __func__ << " " << fg << " accounted_rstat " << pf->rstat << dendl;
dout(10) << fg << " first " << dir->first << " -> " << fgfirst
<< " on " << *dir << dendl;
dir->first = fgfirst;
- dir->fnode.rstat = rstat;
- dir->fnode.accounted_rstat = accounted_rstat;
+ auto _fnode = CDir::allocate_fnode(*dir->get_fnode());
+ _fnode->rstat = rstat;
+ _fnode->accounted_rstat = accounted_rstat;
+ dir->reset_fnode(std::move(_fnode));
dir->dirty_old_rstat.swap(dirty_old_rstat);
if (!(rstat == accounted_rstat) || !dir->dirty_old_rstat.empty()) {
dout(10) << fg << " setting nestlock updated flag" << dendl;
dout(10) << fg << " first " << dir->first << " -> " << fgfirst
<< " on " << *dir << dendl;
dir->first = fgfirst;
- fnode_t *pf = dir->get_projected_fnode();
+ const auto& pf = dir->get_projected_fnode();
finish_scatter_update(&nestlock, dir,
_inode->rstat.version, pf->accounted_rstat.version);
}
for (const auto &p : dirfrags) {
frag_t fg = p.first;
CDir *dir = p.second;
- fnode_t *pf = dir->get_projected_fnode();
+ const auto& pf = dir->get_projected_fnode();
dout(20) << fg << " " << *dir << dendl;
if (!dir->is_auth())
MutationRef mut(new MutationImpl());
mut->ls = mdlog->get_current_segment();
- fnode_t *pf = dir->project_fnode();
+ auto pf = dir->project_fnode();
std::string_view ename;
switch (lock->get_type()) {
ceph_abort();
}
- pf->version = dir->pre_dirty();
- mut->add_projected_fnode(dir);
-
EUpdate *le = new EUpdate(mdlog, ename);
mdlog->start_entry(le);
le->metablob.add_dir_context(dir);
mut->ls->dirty_dirfrag_nest.push_back(&item_dirty_dirfrag_nest);
}
}
+
+ pf->version = dir->pre_dirty();
+ mut->add_projected_fnode(dir);
mdlog->submit_entry(le, new C_Inode_FragUpdate(this, dir, mut));
} else {
dirstat_valid = false;
}
- fnode_t *pf = dir->get_projected_fnode();
+ CDir::fnode_const_ptr pf;
if (update)
pf = dir->project_fnode();
+ else
+ pf = dir->get_projected_fnode();
if (pf->accounted_fragstat.version == pi->dirstat.version - 1) {
dout(20) << fg << " fragstat " << pf->fragstat << dendl;
if (pf->fragstat.nfiles < 0 ||
pf->fragstat.nsubdirs < 0) {
clog->error() << "bad/negative dir size on "
- << dir->dirfrag() << " " << pf->fragstat;
+ << dir->dirfrag() << " " << pf->fragstat;
ceph_assert(!"bad/negative fragstat" == g_conf()->mds_verify_scatter);
-
+
+ auto _pf = const_cast<fnode_t*>(pf.get());
if (pf->fragstat.nfiles < 0)
- pf->fragstat.nfiles = 0;
+ _pf->fragstat.nfiles = 0;
if (pf->fragstat.nsubdirs < 0)
- pf->fragstat.nsubdirs = 0;
+ _pf->fragstat.nsubdirs = 0;
}
if (update) {
- pf->accounted_fragstat = pf->fragstat;
- pf->fragstat.version = pf->accounted_fragstat.version = pi->dirstat.version;
+ auto _pf = const_cast<fnode_t*>(pf.get());
+ _pf->accounted_fragstat = _pf->fragstat;
+ _pf->fragstat.version = _pf->accounted_fragstat.version = pi->dirstat.version;
dout(10) << fg << " updated accounted_fragstat " << pf->fragstat << " on " << *dir << dendl;
}
}
}
- if (pi->dirstat.nfiles < 0 || pi->dirstat.nsubdirs < 0)
- {
+ if (pi->dirstat.nfiles < 0 || pi->dirstat.nsubdirs < 0) {
std::string path;
make_path_string(path);
clog->error() << "Inconsistent statistics detected: fragstat on inode "
rstat_valid = false;
}
- fnode_t *pf = dir->get_projected_fnode();
+ CDir::fnode_const_ptr pf;
if (update)
pf = dir->project_fnode();
+ 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
dout(20) << fg << " skipping STALE accounted_rstat " << pf->accounted_rstat << dendl;
}
if (update) {
- pf->accounted_rstat = pf->rstat;
+ 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->rstat.version = _pf->accounted_rstat.version = pi->rstat.version;
dir->check_rstats();
dout(10) << fg << " updated accounted_rstat " << pf->rstat << " on " << *dir << dendl;
}
if (type == CEPH_LOCK_IDFT)
continue; // nothing to do.
+ if (type == CEPH_LOCK_INEST)
+ dir->assimilate_dirty_rstat_inodes_finish(mut, metablob);
+
dout(10) << " journaling updated frag accounted_ on " << *dir << dendl;
ceph_assert(dir->is_projected());
- fnode_t *pf = dir->get_projected_fnode();
+ 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);
-
- if (type == CEPH_LOCK_INEST)
- dir->assimilate_dirty_rstat_inodes_finish(mut, metablob);
}
}
CDir *dir = p.second;
if (dir->state_test(CDir::STATE_EXPORTBOUND)) {
encode(p.first, bounding);
- encode(dir->fnode.fragstat, bounding);
- encode(dir->fnode.accounted_fragstat, bounding);
- encode(dir->fnode.rstat, bounding);
- encode(dir->fnode.accounted_rstat, bounding);
+ encode(dir->get_fnode()->fragstat, bounding);
+ encode(dir->get_fnode()->accounted_fragstat, bounding);
+ encode(dir->get_fnode()->rstat, bounding);
+ encode(dir->get_fnode()->accounted_rstat, bounding);
dout(10) << " encoded fragstat/rstat info for " << *dir << dendl;
}
}
// check because the dirfrag is under migration? That implies
// it is frozen (and in a SYNC or LOCK state). FIXME.
+ auto _fnode = CDir::allocate_fnode(*dir->get_fnode());
if (dir->is_auth() ||
filelock.get_state() == LOCK_MIX) {
dout(10) << " skipped fragstat info for " << *dir << dendl;
decode(f, q);
decode(f, q);
} else {
- decode(dir->fnode.fragstat, q);
- decode(dir->fnode.accounted_fragstat, q);
+ decode(_fnode->fragstat, q);
+ decode(_fnode->accounted_fragstat, q);
dout(10) << " took fragstat info for " << *dir << dendl;
}
if (dir->is_auth() ||
decode(n, q);
decode(n, q);
} else {
- decode(dir->fnode.rstat, q);
- decode(dir->fnode.accounted_rstat, q);
+ decode(_fnode->rstat, q);
+ decode(_fnode->accounted_rstat, q);
dout(10) << " took rstat info for " << *dir << dendl;
}
+ dir->reset_fnode(std::move(_fnode));
}
_decode_locks_full(p);
for (const auto &p : in->dirfrags) {
CDir *dir = p.second;
ceph_assert(dir->get_version() > 0);
- nest_info.add(dir->fnode.accounted_rstat);
- dir_info.add(dir->fnode.accounted_fragstat);
+ nest_info.add(dir->get_fnode()->accounted_rstat);
+ dir_info.add(dir->get_fnode()->accounted_fragstat);
if (dir->scrub_infop->pending_scrub_error) {
dir->scrub_infop->pending_scrub_error = false;
if (dir->scrub_infop->header->get_repair()) {
le = eu;
}
mds->mdlog->start_entry(le);
- if (update_size) { // FIXME if/when we do max_size nested accounting
- mdcache->predirty_journal_parents(mut, metablob, in, 0, PREDIRTY_PRIMARY);
- // no cow, here!
- CDentry *parent = in->get_projected_parent_dn();
- metablob->add_primary_dentry(parent, in, true);
- } else {
- metablob->add_dir_context(in->get_projected_parent_dn()->get_dir());
- mdcache->journal_dirty_inode(mut.get(), metablob, in);
- }
+
+ mdcache->predirty_journal_parents(mut, metablob, in, 0, PREDIRTY_PRIMARY);
+ // no cow, here!
+ CDentry *parent = in->get_projected_parent_dn();
+ metablob->add_primary_dentry(parent, in, true);
+ mdcache->journal_dirty_inode(mut.get(), metablob, in);
+
mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut,
UPDATE_SHAREMAX, ref_t<MClientCaps>()));
wrlock_force(&in->filelock, mut); // wrlock for duration of journal
adjust_subtree_auth(rootdir, mds->get_nodeid());
rootdir->dir_rep = CDir::REP_ALL; //NONE;
- ceph_assert(rootdir->fnode.accounted_fragstat == rootdir->fnode.fragstat);
- ceph_assert(rootdir->fnode.fragstat == root->get_inode()->dirstat);
- ceph_assert(rootdir->fnode.accounted_rstat == rootdir->fnode.rstat);
+ ceph_assert(rootdir->get_fnode()->accounted_fragstat == rootdir->get_fnode()->fragstat);
+ ceph_assert(rootdir->get_fnode()->fragstat == root->get_inode()->dirstat);
+ ceph_assert(rootdir->get_fnode()->accounted_rstat == rootdir->get_fnode()->rstat);
/* Do no update rootdir rstat information of the fragment, rstat upkeep magic
* assume version 0 is stale/invalid.
*/
rootdir->mark_complete();
- rootdir->mark_dirty(rootdir->pre_dirty(), mds->mdlog->get_current_segment());
+ rootdir->_get_fnode()->version = rootdir->pre_dirty();
+ rootdir->mark_dirty(mds->mdlog->get_current_segment());
rootdir->commit(0, gather->new_sub());
root->store(gather->new_sub());
CInode *my = create_system_inode(MDS_INO_MDSDIR(mds->get_nodeid()), S_IFDIR);
CDir *mydir = my->get_or_open_dirfrag(this, frag_t());
+ auto mydir_fnode = mydir->_get_fnode();
+
adjust_subtree_auth(mydir, mds->get_nodeid());
LogSegment *ls = mds->mdlog->get_current_segment();
CDentry *sdn = mydir->add_primary_dentry(name.str(), stray);
sdn->_mark_dirty(mds->mdlog->get_current_segment());
- stray->_get_inode()->dirstat = straydir->fnode.fragstat;
+ stray->_get_inode()->dirstat = straydir->get_fnode()->fragstat;
- mydir->fnode.rstat.add(stray->get_inode()->rstat);
- mydir->fnode.fragstat.nsubdirs++;
+ mydir_fnode->rstat.add(stray->get_inode()->rstat);
+ mydir_fnode->fragstat.nsubdirs++;
// save them
straydir->mark_complete();
- straydir->mark_dirty(straydir->pre_dirty(), ls);
+ straydir->_get_fnode()->version = straydir->pre_dirty();
+ straydir->mark_dirty(ls);
straydir->commit(0, gather->new_sub());
stray->mark_dirty_parent(ls, true);
stray->store_backtrace(gather->new_sub());
}
- mydir->fnode.accounted_fragstat = mydir->fnode.fragstat;
- mydir->fnode.accounted_rstat = mydir->fnode.rstat;
+ mydir_fnode->accounted_fragstat = mydir->get_fnode()->fragstat;
+ mydir_fnode->accounted_rstat = mydir->get_fnode()->rstat;
auto inode = myin->_get_inode();
- inode->dirstat = mydir->fnode.fragstat;
- inode->rstat = mydir->fnode.rstat;
+ inode->dirstat = mydir->get_fnode()->fragstat;
+ inode->rstat = mydir->get_fnode()->rstat;
++inode->rstat.rsubdirs;
inode->accounted_rstat = inode->rstat;
mydir->mark_complete();
- mydir->mark_dirty(mydir->pre_dirty(), ls);
+ mydir_fnode->version = mydir->pre_dirty();
+ mydir->mark_dirty(ls);
mydir->commit(0, gather->new_sub());
myin->store(gather->new_sub());
mdir = in->get_or_open_dirfrag(this, frag_t());
mdir->mark_complete();
- mdir->pre_dirty();
- } else
+ mdir->_get_fnode()->version = mdir->pre_dirty();
+ } else {
inode->rstat.rfiles = 1;
+ }
+
inode->version = dn->pre_dirty();
SnapRealm *realm = dir->get_inode()->find_snaprealm();
if (in->is_dir()) {
CDir *dir = in->get_dirfrag(frag_t());
ceph_assert(dir);
- dir->mark_dirty(1, mut->ls);
+ dir->mark_dirty(mut->ls);
dir->mark_new(mut->ls);
}
LogSegment *ls = mds->mdlog->get_current_segment();
mydir->state_clear(CDir::STATE_BADFRAG);
mydir->mark_complete();
- mydir->mark_dirty(mydir->pre_dirty(), ls);
+ mydir->_get_fnode()->version = mydir->pre_dirty();
+ mydir->mark_dirty(ls);
}
// open or create stray
snapid_t oldfirst = dn->first;
dn->first = dir_follows+1;
if (realm->has_snaps_in_range(oldfirst, dir_follows)) {
- CDentry *olddn = dn->dir->add_remote_dentry(dn->get_name(), in->ino(), in->d_type(),
- oldfirst, dir_follows);
- olddn->pre_dirty();
+ CDir *dir = dn->dir;
+ CDentry *olddn = dir->add_remote_dentry(dn->get_name(), in->ino(), in->d_type(),
+ oldfirst, dir_follows);
dout(10) << " olddn " << *olddn << dendl;
+ ceph_assert(dir->is_projected());
+ olddn->set_projected_version(dir->get_projected_version());
metablob->add_remote_dentry(olddn, true);
mut->add_cow_dentry(olddn);
// FIXME: adjust link count here? hmm.
}
dout(10) << " dn " << *dn << dendl;
+ CDir *dir = dn->get_dir();
+ ceph_assert(dir->is_projected());
+
if (in) {
CInode *oldin = cow_inode(in, follows);
+ ceph_assert(in->is_projected());
mut->add_cow_inode(oldin);
if (pcow_inode)
*pcow_inode = oldin;
- CDentry *olddn = dn->dir->add_primary_dentry(dn->get_name(), oldin, oldfirst, follows);
- oldin->_get_inode()->version = olddn->pre_dirty();
+ CDentry *olddn = dir->add_primary_dentry(dn->get_name(), oldin, oldfirst, follows);
dout(10) << " olddn " << *olddn << dendl;
bool need_snapflush = !oldin->client_snap_caps.empty();
if (need_snapflush) {
mut->ls->open_files.push_back(&oldin->item_open_file);
mds->locker->mark_need_snapflush_inode(oldin);
}
+ olddn->set_projected_version(dir->get_projected_version());
metablob->add_primary_dentry(olddn, 0, true, false, false, need_snapflush);
mut->add_cow_dentry(olddn);
} else {
ceph_assert(dnl->is_remote());
- CDentry *olddn = dn->dir->add_remote_dentry(dn->get_name(), dnl->get_remote_ino(), dnl->get_remote_d_type(),
+ CDentry *olddn = dir->add_remote_dentry(dn->get_name(), dnl->get_remote_ino(), dnl->get_remote_d_type(),
oldfirst, follows);
- olddn->pre_dirty();
dout(10) << " olddn " << *olddn << dendl;
+
+ olddn->set_projected_version(dir->get_projected_version());
metablob->add_remote_dentry(olddn, true);
mut->add_cow_dentry(olddn);
}
}
}
-
-void MDCache::journal_cow_inode(MutationRef& mut, EMetaBlob *metablob,
- CInode *in, snapid_t follows,
- CInode **pcow_inode)
-{
- dout(10) << "journal_cow_inode follows " << follows << " on " << *in << dendl;
- CDentry *dn = in->get_projected_parent_dn();
- journal_cow_dentry(mut.get(), metablob, dn, follows, pcow_inode);
-}
-
void MDCache::journal_dirty_inode(MutationImpl *mut, EMetaBlob *metablob, CInode *in, snapid_t follows)
{
if (in->is_base()) {
*/
nest_info_t *prstat;
snapid_t first;
- fnode_t *pf = parent->get_projected_fnode();
+ auto pf = parent->_get_projected_fnode();
if (last == CEPH_NOSNAP) {
if (g_conf()->mds_snap_rstat)
first = std::max(ofirst, parent->first);
}
}
-void MDCache::project_rstat_frag_to_inode(nest_info_t& rstat, nest_info_t& accounted_rstat,
+void MDCache::project_rstat_frag_to_inode(const nest_info_t& rstat,
+ const nest_info_t& accounted_rstat,
snapid_t ofirst, snapid_t last,
CInode *pin, bool cow_head)
{
mut->auth_pin(parent);
mut->add_projected_fnode(parent);
- fnode_t *pf = parent->project_fnode();
+ auto pf = parent->project_fnode();
pf->version = parent->pre_dirty();
if (do_parent_mtime || linkunlink) {
EUpdate *le = new EUpdate(mds->mdlog, "truncate finish");
mds->mdlog->start_entry(le);
- CDentry *dn = in->get_projected_parent_dn();
- le->metablob.add_dir_context(dn->get_dir());
- le->metablob.add_primary_dentry(dn, in, true);
- le->metablob.add_truncate_finish(in->ino(), ls->seq);
+ predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY);
journal_dirty_inode(mut.get(), &le->metablob, in);
+ le->metablob.add_truncate_finish(in->ino(), ls->seq);
mds->mdlog->submit_entry(le, new C_MDC_TruncateLogged(this, in, mut));
// flush immediately if there are readers/writers waiting
// journal dirfragtree
auto pi = diri->project_inode();
pi.inode->version = diri->pre_dirty();
+ predirty_journal_parents(mdr, &le->metablob, diri, 0, PREDIRTY_PRIMARY);
journal_dirty_inode(mdr.get(), &le->metablob, diri);
} else {
mds->locker->mark_updated_scatterlock(&diri->dirfragtreelock);
p.second.waiters.push_back(gather->new_sub());
}
+struct C_MDC_FragmentRollback : public MDCacheLogContext {
+ MutationRef mut;
+ C_MDC_FragmentRollback(MDCache *c, MutationRef& m) :
+ MDCacheLogContext(c), mut(m) {}
+ void finish(int r) override {
+ mut->apply();
+ get_mds()->locker->drop_locks(mut.get());
+ mut->cleanup();
+ }
+};
+
void MDCache::rollback_uncommitted_fragments()
{
dout(10) << "rollback_uncommitted_fragments: " << uncommitted_fragments.size() << " pending" << dendl;
dout(10) << " rolling back " << p->first << " refragment by " << uf.bits << " bits" << dendl;
- LogSegment *ls = mds->mdlog->get_current_segment();
+ MutationRef mut(new MutationImpl());
+ mut->ls = mds->mdlog->get_current_segment();
EFragment *le = new EFragment(mds->mdlog, EFragment::OP_ROLLBACK, p->first, uf.bits);
mds->mdlog->start_entry(le);
bool diri_auth = (diri->authority() != CDIR_AUTH_UNDEF);
dirfrag_rollback rollback;
decode(rollback, bp);
- dir->set_version(rollback.fnode.version);
dir->fnode = rollback.fnode;
- dir->_mark_dirty(ls);
+ dir->mark_dirty(mut->ls);
- if (!(dir->fnode.rstat == dir->fnode.accounted_rstat)) {
+ if (!(dir->get_fnode()->rstat == dir->get_fnode()->accounted_rstat)) {
dout(10) << " dirty nestinfo on " << *dir << dendl;
- mds->locker->mark_updated_scatterlock(&dir->inode->nestlock);
- ls->dirty_dirfrag_nest.push_back(&dir->inode->item_dirty_dirfrag_nest);
+ mds->locker->mark_updated_scatterlock(&diri->nestlock);
+ mut->ls->dirty_dirfrag_nest.push_back(&diri->item_dirty_dirfrag_nest);
+ mut->add_updated_lock(&diri->nestlock);
}
- if (!(dir->fnode.fragstat == dir->fnode.accounted_fragstat)) {
+ if (!(dir->get_fnode()->fragstat == dir->get_fnode()->accounted_fragstat)) {
dout(10) << " dirty fragstat on " << *dir << dendl;
- mds->locker->mark_updated_scatterlock(&dir->inode->filelock);
- ls->dirty_dirfrag_dir.push_back(&dir->inode->item_dirty_dirfrag_dir);
+ mds->locker->mark_updated_scatterlock(&diri->filelock);
+ mut->ls->dirty_dirfrag_dir.push_back(&diri->item_dirty_dirfrag_dir);
+ mut->add_updated_lock(&diri->filelock);
}
le->add_orig_frag(dir->get_frag());
if (diri_auth) {
auto pi = diri->project_inode();
+ mut->add_projected_inode(diri);
pi.inode->version = diri->pre_dirty();
- diri->pop_and_dirty_projected_inode(ls); // hacky
+ predirty_journal_parents(mut, &le->metablob, diri, 0, PREDIRTY_PRIMARY);
le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), diri, true);
} else {
mds->locker->mark_updated_scatterlock(&diri->dirfragtreelock);
- ls->dirty_dirfrag_dirfragtree.push_back(&diri->item_dirty_dirfrag_dirfragtree);
+ mut->ls->dirty_dirfrag_dirfragtree.push_back(&diri->item_dirty_dirfrag_dirfragtree);
+ mut->add_updated_lock(&diri->dirfragtreelock);
}
if (g_conf()->mds_debug_frag)
ceph_assert(!diri->dirfragtree.is_leaf(leaf));
}
- mds->mdlog->submit_entry(le);
+ mds->mdlog->submit_entry(le, new C_MDC_FragmentRollback(this, mut));
uf.old_frags.swap(old_frags);
_fragment_committed(p->first, MDRequestRef());
frag_info.nfiles++;
}
- fnode_t *pf = dir->get_projected_fnode();
+ auto pf = dir->get_projected_fnode();
bool good_fragstat = frag_info.same_sums(pf->fragstat);
bool good_rstat = nest_info.same_sums(pf->rstat);
if (good_fragstat && good_rstat) {
return;
}
- pf = dir->project_fnode();
- pf->version = dir->pre_dirty();
+ auto _pf = dir->project_fnode();
+ _pf->version = dir->pre_dirty();
+ pf = _pf;
mdr->add_projected_fnode(dir);
mdr->ls = mds->mdlog->get_current_segment();
frag_info.mtime = pf->fragstat.mtime;
if (pf->fragstat.change_attr > frag_info.change_attr)
frag_info.change_attr = pf->fragstat.change_attr;
- pf->fragstat = frag_info;
+ _pf->fragstat = frag_info;
mds->locker->mark_updated_scatterlock(&diri->filelock);
mdr->ls->dirty_dirfrag_dir.push_back(&diri->item_dirty_dirfrag_dir);
mdr->add_updated_lock(&diri->filelock);
if (!good_rstat) {
if (pf->rstat.rctime > nest_info.rctime)
nest_info.rctime = pf->rstat.rctime;
- pf->rstat = nest_info;
+ _pf->rstat = nest_info;
mds->locker->mark_updated_scatterlock(&diri->nestlock);
mdr->ls->dirty_dirfrag_nest.push_back(&diri->item_dirty_dirfrag_nest);
mdr->add_updated_lock(&diri->nestlock);
CDir *dir = diri->get_dirfrag(leaf);
ceph_assert(dir);
ceph_assert(dir->get_version() > 0);
- dir_info.add(dir->fnode.accounted_fragstat);
- nest_info.add(dir->fnode.accounted_rstat);
+ dir_info.add(dir->get_fnode()->accounted_fragstat);
+ nest_info.add(dir->get_fnode()->accounted_rstat);
}
}
void journal_cow_dentry(MutationImpl *mut, EMetaBlob *metablob, CDentry *dn,
snapid_t follows=CEPH_NOSNAP,
CInode **pcow_inode=0, CDentry::linkage_t *dnl=0);
- void journal_cow_inode(MutationRef& mut, EMetaBlob *metablob, CInode *in, snapid_t follows=CEPH_NOSNAP,
- CInode **pcow_inode=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,
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);
- void project_rstat_frag_to_inode(nest_info_t& rstat, nest_info_t& accounted_rstat,
- snapid_t ofirst, snapid_t last,
- CInode *pin, bool cow_head);
+ void project_rstat_frag_to_inode(const nest_info_t& rstat, const nest_info_t& accounted_rstat,
+ snapid_t ofirst, snapid_t last, CInode *pin, bool cow_head);
void broadcast_quota_to_client(CInode *in, client_t exclude_ct = -1, bool quota_change = false);
void predirty_journal_parents(MutationRef mut, EMetaBlob *blob,
CInode *in, CDir *parent,
friend class C_MDC_FragmentPrep;
friend class C_MDC_FragmentStore;
friend class C_MDC_FragmentCommit;
+ friend class C_MDC_FragmentRollback;
friend class C_IO_MDC_FragmentPurgeOld;
// -- subtrees --
void MutationImpl::apply()
{
pop_and_dirty_projected_inodes();
- pop_and_dirty_projected_fnodes();
- for (const auto& in : dirty_cow_inodes) {
+ for (const auto& in : dirty_cow_inodes)
in->_mark_dirty(ls);
- }
- for (const auto& [dentry, v] : dirty_cow_dentries) {
- dentry->mark_dirty(v, ls);
- }
-
+
+ for (const auto& [dn, v] : dirty_cow_dentries)
+ dn->mark_dirty(v, ls);
+
+ pop_and_dirty_projected_fnodes();
+
for (const auto& lock : updated_locks) {
lock->mark_dirty();
}
if (newi->is_dir()) {
CDir *dir = newi->get_dirfrag(frag_t());
ceph_assert(dir);
- dir->fnode.version--;
- dir->mark_dirty(dir->fnode.version + 1, mdr->ls);
+ dir->mark_dirty(mdr->ls);
dir->mark_new(mdr->ls);
}
CDir *newdir = newi->get_or_open_dirfrag(mdcache, frag_t());
newdir->state_set(CDir::STATE_CREATING);
newdir->mark_complete();
- newdir->fnode.version = newdir->pre_dirty();
+ newdir->_get_fnode()->version = newdir->pre_dirty();
// prepare finisher
mdr->ls = mdlog->get_current_segment();
rollback.reqid = mdr->reqid;
rollback.ino = targeti->ino();
rollback.old_ctime = targeti->get_inode()->ctime; // we hold versionlock xlock; no concorrent projections
- const fnode_t *pf = targeti->get_parent_dn()->get_dir()->get_projected_fnode();
+ const auto& pf = targeti->get_parent_dn()->get_dir()->get_projected_fnode();
rollback.old_dir_mtime = pf->fragstat.mtime;
rollback.old_dir_rctime = pf->rstat.rctime;
rollback.was_inc = inc;
// parent dir rctime
CDir *parent = in->get_projected_parent_dn()->get_dir();
- fnode_t *pf = parent->project_fnode();
+ auto pf = parent->project_fnode();
mut->add_projected_fnode(parent);
pf->version = parent->pre_dirty();
if (pf->fragstat.mtime == pi.inode->ctime) {
auto&& ls = in->get_dirfrags();
for (const auto& dir : ls) {
- const fnode_t *pf = dir->get_projected_fnode();
+ const auto& pf = dir->get_projected_fnode();
if (pf->fragstat.size()) {
dout(10) << "dir_is_nonempty dirstat has "
<< pf->fragstat.size() << " items " << *dir << dendl;
PREDIRTY_PRIMARY|PREDIRTY_DIR, 1);
}
}
+
+ if (srcdnl->is_remote() && srci->is_auth()) {
+ CDir *srci_dir = srci->get_projected_parent_dir();
+ if (srci_dir != srcdn->get_dir() && srci_dir != destdn->get_dir())
+ mdcache->predirty_journal_parents(mdr, metablob, srci, srci_dir, PREDIRTY_PRIMARY);
+ }
// move srcdn
int predirty_primary = (srcdnl->is_primary() && srcdn->get_dir() != destdn->get_dir()) ? PREDIRTY_PRIMARY:0;
mdcache->shutdown_export_stray_finish(migrated_stray);
}
-void _rollback_repair_dir(MutationRef& mut, CDir *dir, rename_rollback::drec &r, utime_t ctime,
- bool isdir, int linkunlink, nest_info_t &rstat)
+static void _rollback_repair_dir(MutationRef& mut, CDir *dir,
+ rename_rollback::drec &r, utime_t ctime,
+ bool isdir, const nest_info_t &rstat)
{
- fnode_t *pf;
- pf = dir->project_fnode();
+ auto pf = dir->project_fnode();
mut->add_projected_fnode(dir);
pf->version = dir->pre_dirty();
if (isdir) {
- pf->fragstat.nsubdirs += linkunlink;
+ pf->fragstat.nsubdirs += 1;
} else {
- pf->fragstat.nfiles += linkunlink;
+ pf->fragstat.nfiles += 1;
}
if (r.ino) {
- pf->rstat.rbytes += linkunlink * rstat.rbytes;
- pf->rstat.rfiles += linkunlink * rstat.rfiles;
- pf->rstat.rsubdirs += linkunlink * rstat.rsubdirs;
- pf->rstat.rsnaps += linkunlink * rstat.rsnaps;
+ pf->rstat.rbytes += rstat.rbytes;
+ pf->rstat.rfiles += rstat.rfiles;
+ pf->rstat.rsubdirs += rstat.rsubdirs;
+ pf->rstat.rsnaps += rstat.rsnaps;
}
if (pf->fragstat.mtime == ctime) {
pf->fragstat.mtime = r.dirfrag_old_mtime;
map<client_t,ref_t<MClientSnap>> splits[2];
- CInode::mempool_inode *pip = nullptr;
+ const CInode::mempool_inode *pip = nullptr;
if (in) {
bool projected;
- if (in->get_projected_parent_dn()->authority().first == whoami) {
+ CDir *pdir = in->get_projected_parent_dir();
+ if (pdir->authority().first == whoami) {
auto pi = in->project_inode();
- pip = pi.inode.get();
mut->add_projected_inode(in);
- pip->version = in->pre_dirty();
+ pi.inode->version = in->pre_dirty();
+ if (pdir != srcdir) {
+ auto pf = pdir->project_fnode();
+ mut->add_projected_fnode(pdir);
+ pf->version = pdir->pre_dirty();
+ }
+ if (pi.inode->ctime == rollback.ctime)
+ pi.inode->ctime = rollback.orig_src.old_ctime;
projected = true;
} else {
- // FIXME: pip = in->get_projected_inode();
+ if (in->get_inode()->ctime == rollback.ctime) {
+ auto _inode = CInode::allocate_inode(*in->get_inode());
+ _inode->ctime = rollback.orig_src.old_ctime;
+ in->reset_inode(_inode);
+ }
projected = false;
}
- if (pip->ctime == rollback.ctime)
- pip->ctime = rollback.orig_src.old_ctime;
+ pip = in->get_projected_inode().get();
if (rollback.srci_snapbl.length() && in->snaprealm) {
bool hadrealm;
}
}
- if (srcdn && srcdn->authority().first == whoami) {
- nest_info_t blah;
- _rollback_repair_dir(mut, srcdir, rollback.orig_src, rollback.ctime,
- in ? in->is_dir() : false, 1, pip ? pip->accounted_rstat : blah);
- }
-
// repair dest
if (destdn) {
if (rollback.orig_dest.ino && target) {
if (target) {
bool projected;
- CInode::mempool_inode *ti = nullptr;
- if (target->get_projected_parent_dn()->authority().first == whoami) {
+ CInode::inode_ptr ti;
+ CDir *pdir = target->get_projected_parent_dir();
+ if (pdir->authority().first == whoami) {
auto pi = target->project_inode();
- ti = pi.inode.get();
mut->add_projected_inode(target);
- ti->version = target->pre_dirty();
+ pi.inode->version = target->pre_dirty();
+ if (pdir != srcdir) {
+ auto pf = pdir->project_fnode();
+ mut->add_projected_fnode(pdir);
+ pf->version = pdir->pre_dirty();
+ }
+ ti = pi.inode;
projected = true;
} else {
- //FIXME: ti = target->get_projected_inode();
+ ti = CInode::allocate_inode(*target->get_inode());
projected = false;
}
+
if (ti->ctime == rollback.ctime)
ti->ctime = rollback.orig_dest.old_ctime;
if (MDS_INO_IS_STRAY(rollback.orig_src.dirfrag.ino)) {
} else
ti->nlink++;
+ if (!projected)
+ target->reset_inode(ti);
+
if (rollback.desti_snapbl.length() && target->snaprealm) {
bool hadrealm;
auto p = rollback.desti_snapbl.cbegin();
}
}
+ if (srcdn && srcdn->authority().first == whoami) {
+ nest_info_t blah;
+ _rollback_repair_dir(mut, srcdir, rollback.orig_src, rollback.ctime,
+ in && in->is_dir(), pip ? pip->accounted_rstat : blah);
+ }
+
if (srcdn)
dout(0) << " srcdn back to " << *srcdn << dendl;
if (in)
class C_PurgeStrayLogged : public StrayManagerLogContext {
CDentry *dn;
version_t pdv;
- LogSegment *ls;
+ MutationRef mut;
public:
- C_PurgeStrayLogged(StrayManager *sm_, CDentry *d, version_t v, LogSegment *s) :
- StrayManagerLogContext(sm_), dn(d), pdv(v), ls(s) { }
+ C_PurgeStrayLogged(StrayManager *sm_, CDentry *d, version_t v, MutationRef& m) :
+ StrayManagerLogContext(sm_), dn(d), pdv(v), mut(m) { }
void finish(int r) override {
- sm->_purge_stray_logged(dn, pdv, ls);
+ sm->_purge_stray_logged(dn, pdv, mut);
}
};
class C_TruncateStrayLogged : public StrayManagerLogContext {
CDentry *dn;
- LogSegment *ls;
+ MutationRef mut;
public:
- C_TruncateStrayLogged(StrayManager *sm, CDentry *d, LogSegment *s) :
- StrayManagerLogContext(sm), dn(d), ls(s) { }
+ C_TruncateStrayLogged(StrayManager *sm, CDentry *d, MutationRef& m) :
+ StrayManagerLogContext(sm), dn(d), mut(m) {}
void finish(int r) override {
- sm->_truncate_stray_logged(dn, ls);
+ sm->_truncate_stray_logged(dn, mut);
}
};
if (only_head) {
/* This was a ::truncate */
- EUpdate *le = new EUpdate(mds->mdlog, "purge_stray truncate");
- mds->mdlog->start_entry(le);
+ MutationRef mut(new MutationImpl());
+ mut->ls = mds->mdlog->get_current_segment();
auto pi = in->project_inode();
+ mut->add_projected_inode(in);
pi.inode->size = 0;
pi.inode->max_size_ever = 0;
pi.inode->client_ranges.clear();
pi.inode->truncate_from = 0;
pi.inode->version = in->pre_dirty();
- le->metablob.add_dir_context(dn->dir);
- le->metablob.add_primary_dentry(dn, in, true);
+ CDir *dir = dn->get_dir();
+ auto pf = dir->project_fnode();
+ mut->add_projected_fnode(dir);
+ pf->version = dir->pre_dirty();
- mds->mdlog->submit_entry(le,
- new C_TruncateStrayLogged(
- this, dn, mds->mdlog->get_current_segment()));
+ EUpdate *le = new EUpdate(mds->mdlog, "purge_stray truncate");
+ mds->mdlog->start_entry(le);
+
+ le->metablob.add_dir_context(dir);
+ auto& dl = le->metablob.add_dir(dn->dir, true);
+ le->metablob.add_primary_dentry(dl, dn, in, EMetaBlob::fullbit::STATE_DIRTY);
+
+ mds->mdlog->submit_entry(le, new C_TruncateStrayLogged(this, dn, mut));
} else {
if (in->get_num_ref() != (int)in->is_dirty() ||
dn->get_num_ref() !=
ceph_abort_msg("rogue reference to purging inode");
}
+ MutationRef mut(new MutationImpl());
+ mut->ls = mds->mdlog->get_current_segment();
+
// kill dentry.
version_t pdv = dn->pre_dirty();
dn->push_projected_linkage(); // NULL
// update dirfrag fragstat, rstat
CDir *dir = dn->get_dir();
- fnode_t *pf = dir->project_fnode();
+ auto pf = dir->project_fnode();
+ mut->add_projected_fnode(dir);
pf->version = dir->pre_dirty();
if (in->is_dir())
pf->fragstat.nsubdirs--;
pf->rstat.sub(in->get_inode()->accounted_rstat);
le->metablob.add_dir_context(dn->dir);
- EMetaBlob::dirlump& dl = le->metablob.add_dir(dn->dir, true);
+ auto& dl = le->metablob.add_dir(dn->dir, true);
le->metablob.add_null_dentry(dl, dn, true);
le->metablob.add_destroyed_inode(in->ino());
- mds->mdlog->submit_entry(le, new C_PurgeStrayLogged(this, dn, pdv,
- mds->mdlog->get_current_segment()));
+ mds->mdlog->submit_entry(le, new C_PurgeStrayLogged(this, dn, pdv, mut));
}
}
-void StrayManager::_purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls)
+void StrayManager::_purge_stray_logged(CDentry *dn, version_t pdv, MutationRef& mut)
{
CInode *in = dn->get_linkage()->get_inode();
CDir *dir = dn->get_dir();
ceph_assert(dn->get_projected_linkage()->is_null());
dir->unlink_inode(dn, !new_dn);
dn->pop_projected_linkage();
- dn->mark_dirty(pdv, ls);
+ dn->mark_dirty(pdv, mut->ls);
- dir->pop_and_dirty_projected_fnode(ls);
+ mut->apply();
in->state_clear(CInode::STATE_ORPHAN);
dn->state_clear(CDentry::STATE_PURGING | CDentry::STATE_PURGINGPINNED);
this, dn, true));
}
-void StrayManager::_truncate_stray_logged(CDentry *dn, LogSegment *ls)
+void StrayManager::_truncate_stray_logged(CDentry *dn, MutationRef& mut)
{
CInode *in = dn->get_projected_linkage()->get_inode();
dout(10) << __func__ << ": " << *dn << " " << *in << dendl;
- in->pop_and_dirty_projected_inode(ls);
+ mut->apply();
in->state_clear(CInode::STATE_PURGING);
dn->state_clear(CDentry::STATE_PURGING | CDentry::STATE_PURGINGPINNED);
#include "include/common_fwd.h"
#include "include/elist.h"
#include <list>
-#include "mds/PurgeQueue.h"
+#include "Mutation.h"
+#include "PurgeQueue.h"
class MDSRank;
class CInode;
*/
void _purge_stray_purged(CDentry *dn, bool only_head);
- void _purge_stray_logged(CDentry *dn, version_t pdv, LogSegment *ls);
+ void _purge_stray_logged(CDentry *dn, version_t pdv, MutationRef& mut);
/**
* Callback: we have logged the update to an inode's metadata
* reflecting it's newly-zeroed length.
*/
- void _truncate_stray_logged(CDentry *dn, LogSegment *ls);
+ void _truncate_stray_logged(CDentry *dn, MutationRef &mut);
/**
* Call this on a dentry that has been identified as
* eligible for purging. It will be passed on to PurgeQueue.
#include "EMetaBlob.h"
struct dirfrag_rollback {
- fnode_t fnode;
+ CDir::fnode_const_ptr fnode;
dirfrag_rollback() { }
void encode(bufferlist& bl) const;
void decode(bufferlist::const_iterator& bl);
static const int STATE_DIRTYDFT = (1<<5); // dirty dirfragtree
//version_t dirv;
- fnode_t fnode;
+ CDir::fnode_const_ptr fnode;
__u32 state;
__u32 nfull, nremote, nnull;
}
void print(dirfrag_t dirfrag, ostream& out) const {
- out << "dirlump " << dirfrag << " v " << fnode.version
+ out << "dirlump " << dirfrag << " v " << fnode->version
<< " state " << state
<< " num " << nfull << "/" << nremote << "/" << nnull
<< std::endl;
}
dirlump& add_dir(CDir *dir, bool dirty, bool complete=false) {
- return add_dir(dir->dirfrag(), dir->get_projected_fnode(), dir->get_projected_version(),
+ return add_dir(dir->dirfrag(), dir->get_projected_fnode(),
dirty, complete);
}
dirlump& add_new_dir(CDir *dir) {
- return add_dir(dir->dirfrag(), dir->get_projected_fnode(), dir->get_projected_version(),
+ return add_dir(dir->dirfrag(), dir->get_projected_fnode(),
true, true, true); // dirty AND complete AND new
}
dirlump& add_import_dir(CDir *dir) {
// dirty=false would be okay in some cases
- return add_dir(dir->dirfrag(), dir->get_projected_fnode(), dir->get_projected_version(),
+ return add_dir(dir->dirfrag(), dir->get_projected_fnode(),
dir->is_dirty(), dir->is_complete(), false, true, dir->is_dirty_dft());
}
dirlump& add_fragmented_dir(CDir *dir, bool dirty, bool dirtydft) {
- return add_dir(dir->dirfrag(), dir->get_projected_fnode(), dir->get_projected_version(),
+ return add_dir(dir->dirfrag(), dir->get_projected_fnode(),
dirty, false, false, false, dirtydft);
}
- dirlump& add_dir(dirfrag_t df, const fnode_t *pf, version_t pv, bool dirty,
+ dirlump& add_dir(dirfrag_t df, const CDir::fnode_const_ptr& pf, bool dirty,
bool complete=false, bool isnew=false,
bool importing=false, bool dirty_dft=false) {
if (lump_map.count(df) == 0)
lump_order.push_back(df);
dirlump& l = lump_map[df];
- l.fnode = *pf;
- l.fnode.version = pv;
+ l.fnode = pf;
if (complete) l.mark_complete();
if (dirty) l.mark_dirty();
if (isnew) l.mark_new();
void EMetaBlob::dirlump::encode(bufferlist& bl, uint64_t features) const
{
ENCODE_START(2, 2, bl);
- encode(fnode, bl);
+ encode(*fnode, bl);
encode(state, bl);
encode(nfull, bl);
encode(nremote, bl);
void EMetaBlob::dirlump::decode(bufferlist::const_iterator &bl)
{
DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl)
- decode(fnode, bl);
+ {
+ auto _fnode = CDir::allocate_fnode();
+ decode(*_fnode, bl);
+ fnode = std::move(_fnode);
+ }
decode(state, bl);
decode(nfull, bl);
decode(nremote, bl);
me->_decode_bits();
}
f->open_object_section("fnode");
- fnode.dump(f);
+ fnode->dump(f);
f->close_section(); // fnode
f->dump_string("state", state_string());
f->dump_int("nfull", nfull);
void EMetaBlob::dirlump::generate_test_instances(std::list<dirlump*>& ls)
{
- ls.push_back(new dirlump());
+ auto dl = new dirlump();
+ dl->fnode = CDir::allocate_fnode();
+ ls.push_back(dl);
}
/**
dout(10) << "EMetaBlob.replay added dir " << *dir << dendl;
}
- dir->set_version( lump.fnode.version );
- dir->fnode = lump.fnode;
+ dir->reset_fnode(std::move(lump.fnode));
+ dir->update_projected_version();
if (lump.is_importing()) {
dir->state_set(CDir::STATE_AUTH);
if (lump.is_dirty()) {
dir->_mark_dirty(logseg);
- if (!(dir->fnode.rstat == dir->fnode.accounted_rstat)) {
+ if (!(dir->get_fnode()->rstat == dir->get_fnode()->accounted_rstat)) {
dout(10) << "EMetaBlob.replay dirty nestinfo on " << *dir << dendl;
mds->locker->mark_updated_scatterlock(&dir->inode->nestlock);
logseg->dirty_dirfrag_nest.push_back(&dir->inode->item_dirty_dirfrag_nest);
} else {
dout(10) << "EMetaBlob.replay clean nestinfo on " << *dir << dendl;
}
- if (!(dir->fnode.fragstat == dir->fnode.accounted_fragstat)) {
+ if (!(dir->get_fnode()->fragstat == dir->get_fnode()->accounted_fragstat)) {
dout(10) << "EMetaBlob.replay dirty fragstat on " << *dir << dendl;
mds->locker->mark_updated_scatterlock(&dir->inode->filelock);
logseg->dirty_dirfrag_dir.push_back(&dir->inode->item_dirty_dirfrag_dir);
void dirfrag_rollback::encode(bufferlist &bl) const
{
ENCODE_START(1, 1, bl);
- encode(fnode, bl);
+ encode(*fnode, bl);
ENCODE_FINISH(bl);
}
void dirfrag_rollback::decode(bufferlist::const_iterator &bl)
{
DECODE_START(1, bl);
- decode(fnode, bl);
+ {
+ auto _fnode = CDir::allocate_fnode();
+ decode(*_fnode, bl);
+ fnode = std::move(_fnode);
+ }
DECODE_FINISH(bl);
}
try {
old_fnode.decode(old_fnode_iter);
dout(4) << "frag " << frag_oid.name << " fnode old v" <<
- old_fnode.version << " vs new v" << lump.fnode.version << dendl;
+ old_fnode.version << " vs new v" << lump.fnode->version << dendl;
old_fnode_version = old_fnode.version;
- write_fnode = old_fnode_version < lump.fnode.version;
+ write_fnode = old_fnode_version < lump.fnode->version;
} catch (const buffer::error &err) {
dout(1) << "frag " << frag_oid.name
<< " is corrupt, overwriting" << dendl;
if ((other_pool || write_fnode) && !dry_run) {
dout(4) << "writing fnode to omap header" << dendl;
bufferlist fnode_bl;
- lump.fnode.encode(fnode_bl);
+ lump.fnode->encode(fnode_bl);
if (!other_pool || frag.ino >= MDS_INO_SYSTEM_BASE) {
r = output.omap_set_header(frag_oid.name, fnode_bl);
}
// squash over it with what's in this fullbit
dout(10) << "Existing remote inode in slot to be (maybe) written "
<< "by a full inode from the journal dn '" << fb.dn.c_str()
- << "' with lump fnode version " << lump.fnode.version
+ << "' with lump fnode version " << lump.fnode->version
<< "vs existing fnode version " << old_fnode_version << dendl;
- write_dentry = old_fnode_version < lump.fnode.version;
+ write_dentry = old_fnode_version < lump.fnode->version;
} else if (dentry_type == 'I') {
// Read out inode version to compare with backing store
InodeStore inode;
if (dentry_type == 'L') {
dout(10) << "Existing hardlink inode in slot to be (maybe) written "
<< "by a remote inode from the journal dn '" << rb.dn.c_str()
- << "' with lump fnode version " << lump.fnode.version
+ << "' with lump fnode version " << lump.fnode->version
<< "vs existing fnode version " << old_fnode_version << dendl;
- write_dentry = old_fnode_version < lump.fnode.version;
+ write_dentry = old_fnode_version < lump.fnode->version;
} else if (dentry_type == 'I') {
dout(10) << "Existing full inode in slot to be (maybe) written "
<< "by a remote inode from the journal dn '" << rb.dn.c_str()
- << "' with lump fnode version " << lump.fnode.version
+ << "' with lump fnode version " << lump.fnode->version
<< "vs existing fnode version " << old_fnode_version << dendl;
- write_dentry = old_fnode_version < lump.fnode.version;
+ write_dentry = old_fnode_version < lump.fnode->version;
} else {
dout(4) << "corrupt dentry in backing store, overwriting from "
"journal" << dendl;
if (dentry_type == 'L') {
dout(10) << "Existing hardlink inode in slot to be (maybe) removed "
<< "by null journal dn '" << nb.dn.c_str()
- << "' with lump fnode version " << lump.fnode.version
+ << "' with lump fnode version " << lump.fnode->version
<< "vs existing fnode version " << old_fnode_version << dendl;
- remove_dentry = old_fnode_version < lump.fnode.version;
+ remove_dentry = old_fnode_version < lump.fnode->version;
} else if (dentry_type == 'I') {
dout(10) << "Existing full inode in slot to be (maybe) removed "
<< "by null journal dn '" << nb.dn.c_str()
- << "' with lump fnode version " << lump.fnode.version
+ << "' with lump fnode version " << lump.fnode->version
<< "vs existing fnode version " << old_fnode_version << dendl;
- remove_dentry = old_fnode_version < lump.fnode.version;
+ remove_dentry = old_fnode_version < lump.fnode->version;
} else {
dout(4) << "corrupt dentry in backing store, will remove" << dendl;
remove_dentry = true;