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;
prepare_old_fragment(replay);
nest_info_t rstatdiff;
frag_info_t fragstatdiff;
- bool touched_mtime;
+ bool touched_mtime, touched_chattr;
version_t rstat_version = inode->get_projected_inode()->rstat.version;
version_t dirstat_version = inode->get_projected_inode()->dirstat.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,
- &touched_mtime);
+ &touched_mtime, &touched_chattr);
dir->prepare_old_fragment(replay);
assert(is_auth());
inode_t *pi = get_projected_inode();
- bool touched_mtime = false;
+ bool touched_mtime = false, touched_chattr = false;
dout(20) << " orig dirstat " << pi->dirstat << dendl;
pi->dirstat.version++;
for (compact_map<frag_t,CDir*>::iterator p = dirfrags.begin();
if (pf->accounted_fragstat.version == pi->dirstat.version - 1) {
dout(20) << fg << " fragstat " << pf->fragstat << dendl;
dout(20) << fg << " accounted_fragstat " << pf->accounted_fragstat << dendl;
- pi->dirstat.add_delta(pf->fragstat, pf->accounted_fragstat, &touched_mtime);
+ pi->dirstat.add_delta(pf->fragstat, pf->accounted_fragstat, &touched_mtime, &touched_chattr);
} else {
dout(20) << fg << " skipping STALE accounted_fragstat " << pf->accounted_fragstat << dendl;
}
}
if (touched_mtime)
pi->mtime = pi->ctime = pi->dirstat.mtime;
+ if (touched_chattr)
+ pi->change_attr = pi->dirstat.change_attr;
dout(20) << " final dirstat " << pi->dirstat << dendl;
if (dirstat_valid && !dirstat.same_sums(pi->dirstat)) {
version_t v = pi->dirstat.version;
if (pi->dirstat.mtime > dirstat.mtime)
dirstat.mtime = pi->dirstat.mtime;
+ if (pi->dirstat.change_attr > dirstat.change_attr)
+ dirstat.change_attr = pi->dirstat.change_attr;
pi->dirstat = dirstat;
pi->dirstat.version = v;
}
if (do_parent_mtime) {
pf->fragstat.mtime = mut->get_op_stamp();
+ pf->fragstat.change_attr++;
+ dout(10) << "predirty_journal_parents bumping change_attr to " << pf->fragstat.change_attr << " on " << parent << dendl;
if (pf->fragstat.mtime > pf->rstat.rctime) {
dout(10) << "predirty_journal_parents updating mtime on " << *parent << dendl;
pf->rstat.rctime = pf->fragstat.mtime;
if (do_parent_mtime || linkunlink) {
dout(20) << "predirty_journal_parents add_delta " << pf->fragstat << dendl;
dout(20) << "predirty_journal_parents - " << pf->accounted_fragstat << dendl;
- bool touched_mtime = false;
- pi->dirstat.add_delta(pf->fragstat, pf->accounted_fragstat, &touched_mtime);
+ bool touched_mtime = false, touched_chattr = false;
+ pi->dirstat.add_delta(pf->fragstat, pf->accounted_fragstat, &touched_mtime, &touched_chattr);
pf->accounted_fragstat = pf->fragstat;
if (touched_mtime)
pi->mtime = pi->ctime = pi->dirstat.mtime;
+ if (touched_chattr)
+ pi->change_attr = pi->dirstat.change_attr;
dout(20) << "predirty_journal_parents gives " << pi->dirstat << " on " << *pin << dendl;
if (parent->get_frag() == frag_t()) { // i.e., we are the only frag
if (!good_fragstat) {
if (pf->fragstat.mtime > frag_info.mtime)
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;
mds->locker->mark_updated_scatterlock(&diri->filelock);
mdr->ls->dirty_dirfrag_dir.push_back(&diri->item_dirty_dirfrag_dir);
void frag_info_t::encode(bufferlist &bl) const
{
- ENCODE_START(2, 2, bl);
+ ENCODE_START(3, 2, bl);
::encode(version, bl);
::encode(mtime, bl);
::encode(nfiles, bl);
::encode(nsubdirs, bl);
+ ::encode(change_attr, bl);
ENCODE_FINISH(bl);
}
void frag_info_t::decode(bufferlist::iterator &bl)
{
- DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
+ DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl);
::decode(version, bl);
::decode(mtime, bl);
::decode(nfiles, bl);
::decode(nsubdirs, bl);
+ if (struct_v >= 3)
+ ::decode(change_attr, bl);
+ else
+ change_attr = 0;
DECODE_FINISH(bl);
}
struct frag_info_t : public scatter_info_t {
// this frag
utime_t mtime;
+ uint64_t change_attr;
int64_t nfiles; // files
int64_t nsubdirs; // subdirs
- frag_info_t() : nfiles(0), nsubdirs(0) {}
+ frag_info_t() : change_attr(0), nfiles(0), nsubdirs(0) {}
int64_t size() const { return nfiles + nsubdirs; }
}
// *this += cur - acc;
- void add_delta(const frag_info_t &cur, frag_info_t &acc, bool *touched_mtime=0) {
+ void add_delta(const frag_info_t &cur, frag_info_t &acc, bool *touched_mtime=0, bool *touched_chattr=0) {
if (cur.mtime > mtime) {
mtime = cur.mtime;
if (touched_mtime)
*touched_mtime = true;
}
+ if (cur.change_attr > change_attr) {
+ change_attr = cur.change_attr;
+ if (touched_chattr)
+ *touched_chattr = true;
+ }
nfiles += cur.nfiles - acc.nfiles;
nsubdirs += cur.nsubdirs - acc.nsubdirs;
}
void add(const frag_info_t& other) {
if (other.mtime > mtime)
mtime = other.mtime;
+ if (other.change_attr > change_attr)
+ change_attr = other.change_attr;
nfiles += other.nfiles;
nsubdirs += other.nsubdirs;
}