__u8 fl_pg_pool; /* implies crush ruleset AND object namespace */
};
+struct nested_info_t {
+ uint64_t nested_size; // \sum_{children}(size + nested_size)
+ utime_t nested_ctime; // \max_{children}(ctime, nested_ctime)
+
+ void encode(bufferlist &bl) const {
+ ::encode(nested_size, bl);
+ ::encode(nested_ctime, bl);
+ }
+ void decode(bufferlist::iterator &bl) {
+ ::decode(nested_size, bl);
+ ::decode(nested_ctime, bl);
+ }
+};
+WRITE_CLASS_ENCODER(nested_info_t)
+
struct inode_t {
// base (immutable)
inodeno_t ino;
utime_t atime; // file data access time.
uint64_t time_warp_seq; // count of (potential) mtime/atime timewarps (i.e., utimes())
- // recursive accounting
- uint64_t nested_size; // \sum_{children}(size + nested_size)
- utime_t nested_ctime; // \max_{children}(ctime, nested_ctime)
+ // dirfrag, recursive accounting
+ nested_info_t nested; // inline summation
// special stuff
version_t version; // auth only
::encode(i.max_size, bl);
::encode(i.mtime, bl);
::encode(i.atime, bl);
- ::encode(i.rmtime, bl);
+ ::encode(i.nested, bl);
::encode(i.version, bl);
::encode(i.file_data_version, bl);
}
::decode(i.max_size, p);
::decode(i.mtime, p);
::decode(i.atime, p);
- ::decode(i.rmtime, p);
+ ::decode(i.nested, p);
::decode(i.version, p);
::decode(i.file_data_version, p);
}
break;
case CEPH_LOCK_IDIR:
- ::encode(inode.mtime, bl);
- if (0) {
+ {
+ ::encode(inode.size, bl);
+ ::encode(inode.mtime, bl);
map<frag_t,int> frag_sizes;
for (map<frag_t,CDir*>::iterator p = dirfrags.begin();
p != dirfrags.end();
++p)
if (p->second->is_auth()) {
- //frag_t fg = (*p)->get_frag();
- //frag_sizes[f] = dirfrag_size[fg];
+ frag_t fg = (*p)->get_frag();
+ frag_sizes[f] = dirfrag_size[fg];
}
::encode(frag_sizes, bl);
}
break;
case CEPH_LOCK_INESTED:
- //_encode(inode.nested_ctime, bl);
- //_encode(inode.nested_size, bl);
+ {
+ map<frag_t,nested_info_t> dfn;
+ for (map<frag_t,CDir*>::iterator p = dirfrags.begin();
+ p != dirfrags.end();
+ ++p)
+ if (p->second->is_auth()) {
+ frag_t fg = (*p)->get_frag();
+ dfn[fg] = dirfrag_nested[fg];
+ }
+ ::encode(dfn, bl);
+ }
break;
default:
void CInode::decode_lock_state(int type, bufferlist& bl)
{
bufferlist::iterator p = bl.begin();
- utime_t tm;
switch (type) {
case CEPH_LOCK_IAUTH:
break;
case CEPH_LOCK_IDIR:
- //::_decode(inode.size, p);
- ::decode(tm, p);
- if (inode.mtime < tm) {
- inode.mtime = tm;
- if (is_auth()) {
- dout(10) << "decode_lock_state auth got mtime " << tm << " > my " << inode.mtime
- << ", setting dirlock updated flag on " << *this
- << dendl;
- dirlock.set_updated();
- }
- }
- if (0) {
+ {
+ utime_t tm;
+ uint64_t sz;
map<frag_t,int> dfsz;
+ ::decode(sz, p);
+ ::decode(tm, p);
::decode(dfsz, p);
- // hmm which to keep?
+
+ if (is_auth()) {
+ if (tm > inode.mtime) {
+ dout(10) << "decode_lock_state auth got mtime " << tm << " > my " << inode.mtime
+ << ", setting dirlock updated flag on " << *this
+ << dendl;
+ inode.mtime = tm;
+ dirlock.set_updated();
+ }
+ for (map<frag_t,int>::iterator p = dfsz.begin(); p != dfsz.end(); ++p) {
+ dirfragtree.force_to_leaf(p->first);
+ dirfrag_size[p->first] = p->second;
+ }
+ } else {
+ inode.mtime = tm;
+ inode.size = sz;
+ dirfrag_size.swap(dfsz);
+ }
}
break;
break;
case CEPH_LOCK_INESTED:
- // ***
+ {
+ map<frag_t,nested_info_t> dfn;
+ ::decode(dfn, p);
+ for (map<frag_t,nested_info_t>::iterator p = dfn.begin(); p != dfn.end(); ++p) {
+ dirfragtree.force_to_leaf(p->first);
+ dirfrag_nested[p->first] = p->second;
+ }
+ }
break;
default:
case CEPH_LOCK_IDIR:
xlist_dirty_inode_mtime.remove_myself();
break;
+ case CEPH_LOCK_INESTED:
+ assert(0); // hmm!
+ break;
default:
assert(0);
}
map<string, bufferptr> xattrs;
fragtree_t dirfragtree; // dir frag tree, if any. always consistent with our dirfrag map.
map<frag_t,int> dirfrag_size; // size of each dirfrag
+ map<frag_t,nested_info_t> dirfrag_nested;
off_t last_journaled; // log offset for the last time i was journaled
off_t last_open_journaled; // log offset for the last journaled EOpen
return file_eval_gather((FileLock*)lock);
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
return scatter_eval_gather((ScatterLock*)lock);
default:
return simple_eval_gather(lock);
return file_rdlock_start((FileLock*)lock, mdr);
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
return scatter_rdlock_start((ScatterLock*)lock, mdr);
default:
return simple_rdlock_start(lock, mdr);
return file_rdlock_finish((FileLock*)lock, mdr);
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
return scatter_rdlock_finish((ScatterLock*)lock, mdr);
default:
return simple_rdlock_finish(lock, mdr);
switch (lock->get_type()) {
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
return scatter_wrlock_start((ScatterLock*)lock, mdr);
case CEPH_LOCK_IVERSION:
return local_wrlock_start((LocalLock*)lock, mdr);
switch (lock->get_type()) {
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
return scatter_wrlock_finish((ScatterLock*)lock, mdr);
case CEPH_LOCK_IVERSION:
return local_wrlock_finish((LocalLock*)lock, mdr);
return local_xlock_start((LocalLock*)lock, mdr);
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
assert(0);
default:
return simple_xlock_start(lock, mdr);
return local_xlock_finish((LocalLock*)lock, mdr);
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
assert(0);
default:
return simple_xlock_finish(lock, mdr);
case CEPH_LOCK_IFILE:
case CEPH_LOCK_IDIR:
case CEPH_LOCK_IXATTR:
+ case CEPH_LOCK_INESTED:
{
CInode *in = mdcache->get_inode(info.ino);
if (!in) {
case CEPH_LOCK_IFILE: return &in->filelock;
case CEPH_LOCK_IDIR: return &in->dirlock;
case CEPH_LOCK_IXATTR: return &in->xattrlock;
+ case CEPH_LOCK_INESTED: return &in->nestedlock;
}
}
case CEPH_LOCK_IDFT:
case CEPH_LOCK_IDIR:
+ case CEPH_LOCK_INESTED:
handle_scatter_lock((ScatterLock*)lock, m);
break;