if (is_dirty())
mark_clean();
}
-
- void decode_import_state(bufferlist& bl, int& off, int from, int to, LogSegment *ls) {
+ void decode_import(bufferlist::iterator& blp, LogSegment *ls) {
int nstate;
- bl.copy(off, sizeof(nstate), (char*)&nstate);
- off += sizeof(nstate);
- bl.copy(off, sizeof(version), (char*)&version);
- off += sizeof(version);
- bl.copy(off, sizeof(projected_version), (char*)&projected_version);
- off += sizeof(projected_version);
- lock._decode(bl, off);
- ::_decode(replica_map, bl, off);
+ ::_decode_simple(nstate, blp);
+ ::_decode_simple(version, blp);
+ ::_decode_simple(projected_version, blp);
+ lock._decode(blp);
+ ::_decode_simple(replica_map, blp);
// twiddle
state = 0;
_mark_dirty(ls);
if (!replica_map.empty())
get(PIN_REPLICATED);
- add_replica(from, EXPORT_NONCE);
- if (is_replica(to))
- remove_replica(to);
}
// -- locking --
+// IMPORT/EXPORT
+
+void CDir::encode_export(bufferlist& bl)
+{
+ ::_encode_simple(version, bl);
+ ::_encode_simple(committed_version, bl);
+ ::_encode_simple(committed_version_equivalent, bl);
+
+ ::_encode_simple(state, bl);
+ ::_encode_simple(dir_rep, bl);
+
+ ::_encode_simple(pop_me, bl);
+ ::_encode_simple(pop_auth_subtree, bl);
+
+ ::_encode_simple(dir_rep_by, bl);
+ ::_encode_simple(replica_map, bl);
+}
+
+void CDir::finish_export(utime_t now)
+{
+ pop_auth_subtree_nested -= pop_auth_subtree;
+ pop_me.zero(now);
+ pop_auth_subtree.zero(now);
+}
+
+void CDir::decode_import(bufferlist::iterator& blp)
+{
+ ::_decode_simple(version, blp);
+ ::_decode_simple(committed_version, blp);
+ ::_decode_simple(committed_version_equivalent, blp);
+ committing_version = committed_version;
+ projected_version = version;
+
+ unsigned s;
+ ::_decode_simple(s, blp);
+ state &= MASK_STATE_IMPORT_KEPT;
+ state |= (s & MASK_STATE_EXPORTED);
+ if (is_dirty()) get(PIN_DIRTY);
+
+ ::_decode_simple(dir_rep, blp);
+
+ ::_decode_simple(pop_me, blp);
+ ::_decode_simple(pop_auth_subtree, blp);
+ pop_auth_subtree_nested += pop_auth_subtree;
+
+ ::_decode_simple(dir_rep_by, blp);
+ ::_decode_simple(replica_map, blp);
+ if (!replica_map.empty()) get(PIN_REPLICATED);
+
+ replica_nonce = 0; // no longer defined
+}
+
+
+
/********************************
* AUTHORITY
void finish_waiting(int mask, int result = 0); // ditto
+ // -- import/export --
+ void encode_export(bufferlist& bl);
+ void finish_export(utime_t now);
+ void decode_import(bufferlist::iterator& blp);
+
+
// -- auth pins --
bool can_auth_pin() { return is_auth() && !(is_frozen() || is_freezing()); }
int is_auth_pinned() { return auth_pins; }
};
-// export
-
-class CDirExport {
- struct {
- dirfrag_t dirfrag;
- uint32_t nden; // num dentries (including null ones)
- version_t version;
- version_t committed_version;
- version_t committed_version_equivalent;
- uint32_t state;
- dirfrag_load_vec_t pop_me;
- dirfrag_load_vec_t pop_auth_subtree;
- int32_t dir_rep;
- } st;
- map<int,int> replicas;
- set<int> rep_by;
-
- public:
- CDirExport() {}
- CDirExport(CDir *dir, utime_t now) {
- memset(&st, 0, sizeof(st));
-
- assert(dir->get_version() == dir->get_projected_version());
-
- st.dirfrag = dir->dirfrag();
- st.nden = dir->items.size();
- st.version = dir->version;
- st.committed_version = dir->committed_version;
- st.committed_version_equivalent = dir->committed_version_equivalent;
- st.state = dir->state;
- st.dir_rep = dir->dir_rep;
-
- st.pop_me = dir->pop_me;
- st.pop_auth_subtree = dir->pop_auth_subtree;
- /*
- dir->pop_auth_subtree_nested -= dir->pop_auth_subtree;
- dir->pop_me.zero(now);
- dir->pop_auth_subtree.zero(now);
- */
- rep_by = dir->dir_rep_by;
- replicas = dir->replica_map;
- }
-
- dirfrag_t get_dirfrag() { return st.dirfrag; }
- uint32_t get_nden() { return st.nden; }
-
- void update_dir(CDir *dir) {
- assert(dir->dirfrag() == st.dirfrag);
-
- // set committed_version at old version
- dir->committing_version =
- dir->committed_version = st.committed_version;
- dir->committed_version_equivalent = st.committed_version_equivalent;
- dir->projected_version =
- dir->version = st.version;
-
- // twiddle state
- dir->state = (dir->state & CDir::MASK_STATE_IMPORT_KEPT) | // remember import flag, etc.
- (st.state & CDir::MASK_STATE_EXPORTED);
- dir->dir_rep = st.dir_rep;
-
- dir->pop_me = st.pop_me;
- dir->pop_auth_subtree = st.pop_auth_subtree;
- dir->pop_auth_subtree_nested += dir->pop_auth_subtree;
-
- dir->replica_nonce = 0; // no longer defined
-
- if (!dir->replica_map.empty())
- generic_dout(0) << "replicas not empty non import, " << *dir << ", " << dir->replica_map << dendl;
-
- dir->dir_rep_by = rep_by;
- dir->replica_map = replicas;
- generic_dout(12) << "replicas in export is " << replicas << ", dir now " << dir->replica_map << dendl;
- if (!replicas.empty())
- dir->get(CDir::PIN_REPLICATED);
- if (dir->is_dirty()) {
- dir->get(CDir::PIN_DIRTY);
- }
- }
-
-
- void _encode(bufferlist& bl) {
- bl.append((char*)&st, sizeof(st));
- ::_encode(replicas, bl);
- ::_encode(rep_by, bl);
- }
-
- int _decode(bufferlist& bl, int off = 0) {
- bl.copy(off, sizeof(st), (char*)&st);
- off += sizeof(st);
- ::_decode(replicas, bl, off);
- ::_decode(rep_by, bl, off);
- return off;
- }
-
-};
-
-
#endif
out << " v" << in.get_version();
if (in.state_test(CInode::STATE_AMBIGUOUSAUTH)) out << " AMBIGAUTH";
- if (in.is_freezing_inode()) out << " FREEZING";
+ if (in.is_freezing_inode()) out << " FREEZING=" << in.auth_pin_freeze_allowance;
if (in.is_frozen_inode()) out << " FROZEN";
// locks
assert(auth_pin_allowance > 0); // otherwise we need to adjust parent's nested_auth_pins
assert(auth_pins >= auth_pin_allowance);
if (auth_pins > auth_pin_allowance) {
- dout(10) << "freeze_inode - waiting for auth_pins to drop" << dendl;
- auth_pin_freeze_allowance = auth_pin_freeze_allowance;
+ dout(10) << "freeze_inode - waiting for auth_pins to drop to " << auth_pin_allowance << dendl;
+ auth_pin_freeze_allowance = auth_pin_allowance;
get(PIN_FREEZING);
state_set(STATE_FREEZING);
return false;
+
+// IMPORT/EXPORT
+
+void CInode::encode_export(bufferlist& bl)
+{
+ ::_encode_simple(inode, bl);
+ ::_encode_simple(symlink, bl);
+ dirfragtree._encode(bl);
+
+ bool dirty = is_dirty();
+ ::_encode_simple(dirty, bl);
+
+ ::_encode_simple(pop, bl);
+
+ ::_encode_simple(replica_map, bl);
+
+ map<int,Capability::Export> cap_map;
+ export_client_caps(cap_map);
+ ::_encode_simple(cap_map, bl);
+
+ authlock._encode(bl);
+ linklock._encode(bl);
+ dirfragtreelock._encode(bl);
+ filelock._encode(bl);
+ dirlock._encode(bl);
+}
+
+void CInode::finish_export(utime_t now)
+{
+ pop.zero(now);
+}
+
+void CInode::decode_import(bufferlist::iterator& p,
+ set<int>& new_client_caps,
+ LogSegment *ls)
+{
+ ::_decode_simple(inode, p);
+ ::_decode_simple(symlink, p);
+ dirfragtree._decode(p);
+
+ bool dirty;
+ ::_decode_simple(dirty, p);
+ if (dirty)
+ _mark_dirty(ls);
+
+ ::_decode_simple(pop, p);
+
+ ::_decode_simple(replica_map, p);
+ if (!replica_map.empty()) get(PIN_REPLICATED);
+
+ map<int,Capability::Export> cap_map;
+ ::_decode_simple(cap_map, p);
+ merge_client_caps(cap_map, new_client_caps);
+
+ authlock._decode(p);
+ linklock._decode(p);
+ dirfragtreelock._decode(p);
+ filelock._decode(p);
+ dirlock._decode(p);
+}
// auth pin
int auth_pins;
int nested_auth_pins;
+public:
int auth_pin_freeze_allowance;
public:
void add_waiter(int tag, Context *c);
+ // -- import/export --
+ void encode_export(bufferlist& bl);
+ void finish_export(utime_t now);
+ void decode_import(bufferlist::iterator& p,
+ set<int>& new_client_caps,
+ LogSegment *ls);
+
+
// -- locks --
public:
LocalLock versionlock;
};
-// export
-
-class CInodeExport {
-
- struct st_ {
- inode_t inode;
-
- inode_load_vec_t pop;
-
- bool is_dirty; // dirty inode?
-
- int num_caps;
- } st;
-
- string symlink;
- fragtree_t dirfragtree;
-
- map<int,int> replicas;
- map<int,Capability::Export> cap_map;
-
- bufferlist locks;
-
-public:
- CInodeExport() {}
- CInodeExport(CInode *in, utime_t now) {
- st.inode = in->inode;
- symlink = in->symlink;
- dirfragtree = in->dirfragtree;
-
- st.is_dirty = in->is_dirty();
- replicas = in->replica_map;
-
- in->authlock._encode(locks);
- in->linklock._encode(locks);
- in->dirfragtreelock._encode(locks);
- in->filelock._encode(locks);
- in->dirlock._encode(locks);
-
- st.pop = in->pop;
- in->pop.zero(now);
-
- in->export_client_caps(cap_map);
- }
-
- inodeno_t get_ino() { return st.inode.ino; }
-
- void update_inode(CInode *in, set<int>& new_client_caps, LogSegment *ls) {
- // treat scatterlocked mtime special, since replica may have newer info
- if (in->dirlock.get_state() == LOCK_SCATTER ||
- in->dirlock.get_state() == LOCK_GLOCKC ||
- in->dirlock.get_state() == LOCK_GTEMPSYNCC)
- st.inode.mtime = MAX(in->inode.mtime, st.inode.mtime);
-
- in->inode = st.inode;
- in->symlink = symlink;
- in->dirfragtree = dirfragtree;
-
- in->pop = st.pop;
-
- if (st.is_dirty)
- in->_mark_dirty(ls);
-
- in->replica_map = replicas;
- if (!replicas.empty())
- in->get(CInode::PIN_REPLICATED);
-
- int off = 0;
- in->authlock._decode(locks, off);
- in->linklock._decode(locks, off);
- in->dirfragtreelock._decode(locks, off);
- in->filelock._decode(locks, off);
- in->dirlock._decode(locks, off);
-
- // caps
- in->merge_client_caps(cap_map, new_client_caps);
- }
-
- void _encode(bufferlist& bl) {
- st.num_caps = cap_map.size();
-
- ::_encode(st, bl);
- ::_encode(symlink, bl);
- dirfragtree._encode(bl);
- ::_encode(replicas, bl);
- ::_encode(locks, bl);
- ::_encode(cap_map, bl);
- }
-
- int _decode(bufferlist& bl, int off = 0) {
- ::_decode(st, bl, off);
- ::_decode(symlink, bl, off);
- dirfragtree._decode(bl, off);
- ::_decode(replicas, bl, off);
- ::_decode(locks, bl, off);
- ::_decode(cap_map, bl, off);
-
- return off;
- }
-};
-
-
#endif
// fill export message with cache data
utime_t now = g_clock.now();
map<int,entity_inst_t> exported_client_map;
- list<bufferlist> export_data;
+ bufferlist export_data;
int num_exported_inodes = encode_export_dir( export_data,
dir, // recur start point
exported_client_map,
now );
bufferlist bl;
::_encode(exported_client_map, bl);
- export_data.push_front(bl);
+ bl.claim_append(export_data);
+ export_data.claim(bl);
// send the export data!
MExportDir *req = new MExportDir(dir->dirfrag());
* update our local state for this inode to export.
* encode relevant state to be sent over the wire.
* used by: encode_export_dir, file_rename (if foreign)
+ *
+ * FIXME: the separation between CInode.encode_export and these methods
+ * is pretty arbitrary and dumb.
*/
void Migrator::encode_export_inode(CInode *in, bufferlist& enc_state,
- map<int,entity_inst_t>& exported_client_map,
- utime_t now)
+ map<int,entity_inst_t>& exported_client_map)
{
dout(7) << "encode_export_inode " << *in << dendl;
assert(!in->is_replica(mds->get_nodeid()));
- CInodeExport istate(in, now);
- istate._encode(enc_state);
+ ::_encode_simple(in->inode.ino, enc_state);
+ in->encode_export(enc_state);
// make note of clients named by exported capabilities
for (map<int, Capability>::iterator it = in->client_caps.begin();
exported_client_map[it->first] = mds->clientmap.get_inst(it->first);
}
-void Migrator::finish_export_inode(CInode *in, list<Context*>& finished)
+void Migrator::finish_export_inode(CInode *in, utime_t now, list<Context*>& finished)
{
dout(12) << "finish_export_inode " << *in << dendl;
+ in->finish_export(now);
+
// tell (all) clients about migrating caps.. mark STALE
for (map<int, Capability>::iterator it = in->client_caps.begin();
it != in->client_caps.end();
}
-int Migrator::encode_export_dir(list<bufferlist>& dirstatelist,
+int Migrator::encode_export_dir(bufferlist& exportbl,
CDir *dir,
map<int,entity_inst_t>& exported_client_map,
utime_t now)
assert(dir->get_projected_version() == dir->get_version());
// dir
- bufferlist enc_dir;
- CDirExport dstate(dir, now);
- dstate._encode( enc_dir );
+ dirfrag_t df = dir->dirfrag();
+ ::_encode_simple(df, exportbl);
+ dir->encode_export(exportbl);
+
+ long nden = dir->items.size();
+ ::_encode_simple(nden, exportbl);
// dentries
list<CDir*> subdirs;
dout(7) << "encode_export_dir exporting " << *dn << dendl;
// dn name
- ::_encode(it->first, enc_dir);
+ ::_encode(it->first, exportbl);
// state
- dn->encode_export(enc_dir);
+ dn->encode_export(exportbl);
// points to...
// null dentry?
if (dn->is_null()) {
- enc_dir.append("N", 1); // null dentry
+ exportbl.append("N", 1); // null dentry
continue;
}
if (dn->is_remote()) {
// remote link
- enc_dir.append("L", 1); // remote link
+ exportbl.append("L", 1); // remote link
inodeno_t ino = dn->get_remote_ino();
unsigned char d_type = dn->get_remote_d_type();
- ::_encode(ino, enc_dir);
- ::_encode(d_type, enc_dir);
+ ::_encode(ino, exportbl);
+ ::_encode(d_type, exportbl);
continue;
}
// primary link
// -- inode
- enc_dir.append("I", 1); // inode dentry
+ exportbl.append("I", 1); // inode dentry
- encode_export_inode(in, enc_dir, exported_client_map, now); // encode, and (update state for) export
+ encode_export_inode(in, exportbl, exported_client_map); // encode, and (update state for) export
// directory?
list<CDir*> dfs;
}
}
- // add to dirstatelist
- bufferlist bl;
- dirstatelist.push_back( bl );
- dirstatelist.back().claim( enc_dir );
-
// subdirs
for (list<CDir*>::iterator it = subdirs.begin(); it != subdirs.end(); it++)
- num_exported += encode_export_dir(dirstatelist, *it, exported_client_map, now);
+ num_exported += encode_export_dir(exportbl, *it, exported_client_map, now);
return num_exported;
}
dir->take_waiting(CDir::WAIT_ANY, finished); // all dir waiters
// pop
- dir->pop_auth_subtree_nested -= dir->pop_auth_subtree;
- dir->pop_me.zero(now);
- dir->pop_auth_subtree.zero(now);
+ dir->finish_export(now);
// dentries
list<CDir*> subdirs;
// inode?
if (dn->is_primary()) {
- finish_export_inode(in, finished);
+ finish_export_inode(in, now, finished);
// subdirs?
in->get_nested_dirfrags(subdirs);
// add this crap to my cache
map<int,entity_inst_t> imported_client_map;
- int off = 0;
- ::_decode(imported_client_map, m->get_dirstate().front(), off);
- m->get_dirstate().pop_front();
+ bufferlist::iterator blp = m->get_dirstate().begin();
+ ::_decode_simple(imported_client_map, blp);
int num_imported_inodes = 0;
- while (!m->get_dirstate().empty()) {
+ while (!blp.end()) {
num_imported_inodes +=
- decode_import_dir(m->get_dirstate().front(),
+ decode_import_dir(blp,
oldauth,
dir, // import root
le,
imported_client_map,
mds->mdlog->get_current_segment());
- m->get_dirstate().pop_front();
}
dout(10) << " " << m->get_bounds().size() << " imported bounds" << dendl;
}
-void Migrator::decode_import_inode(CDentry *dn, bufferlist& bl, int& off, int oldauth,
+void Migrator::decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int oldauth,
map<int,entity_inst_t>& imported_client_map,
LogSegment *ls)
{
dout(15) << "decode_import_inode on " << *dn << dendl;
- CInodeExport istate;
- off = istate._decode(bl, off);
+ inodeno_t ino;
+ ::_decode_simple(ino, blp);
bool added = false;
- CInode *in = cache->get_inode(istate.get_ino());
+ CInode *in = cache->get_inode(ino);
if (!in) {
in = new CInode(mds->mdcache);
added = true;
// state after link -- or not! -sage
set<int> merged_client_caps;
- istate.update_inode(in, merged_client_caps, ls);
+ in->decode_import(blp, merged_client_caps, ls);
// link before state -- or not! -sage
if (dn->inode != in) {
}
-int Migrator::decode_import_dir(bufferlist& bl,
+int Migrator::decode_import_dir(bufferlist::iterator& blp,
int oldauth,
CDir *import_root,
EImportStart *le,
map<int,entity_inst_t>& imported_client_map,
LogSegment *ls)
{
- int off = 0;
-
// set up dir
- CDirExport dstate;
- off = dstate._decode(bl, off);
-
- CInode *diri = cache->get_inode(dstate.get_dirfrag().ino);
+ dirfrag_t df;
+ ::_decode_simple(df, blp);
+
+ CInode *diri = cache->get_inode(df.ino);
assert(diri);
- CDir *dir = diri->get_or_open_dirfrag(mds->mdcache, dstate.get_dirfrag().frag);
+ CDir *dir = diri->get_or_open_dirfrag(mds->mdcache, df.frag);
assert(dir);
dout(7) << "decode_import_dir " << *dir << dendl;
// assimilate state
- dstate.update_dir( dir );
+ dir->decode_import(blp);
// mark (may already be marked from get_or_open_dir() above)
if (!dir->is_auth())
dout(15) << "doing contents" << dendl;
// contents
- long nden = dstate.get_nden();
+ long nden;
+ ::_decode_simple(nden, blp);
for (; nden>0; nden--) {
num_imported++;
// dentry
string dname;
- ::_decode(dname, bl, off);
+ ::_decode_simple(dname, blp);
CDentry *dn = dir->lookup(dname);
if (!dn)
dn = dir->add_null_dentry(dname);
- // decode state
- dn->decode_import_state(bl, off, oldauth, mds->get_nodeid(), ls);
+ dn->decode_import(blp, ls);
+
+ dn->add_replica(oldauth, CDentry::EXPORT_NONCE);
+ if (dn->is_replica(mds->get_nodeid()))
+ dn->remove_replica(mds->get_nodeid());
+
dout(15) << "decode_import_dir got " << *dn << dendl;
// points to...
char icode;
- bl.copy(off, 1, &icode);
- off++;
+ ::_decode_simple(icode, blp);
if (icode == 'N') {
// null dentry
// remote link
inodeno_t ino;
unsigned char d_type;
- ::_decode(ino, bl, off);
- ::_decode(d_type, bl, off);
+ ::_decode_simple(ino, blp);
+ ::_decode_simple(d_type, blp);
if (dn->is_remote()) {
assert(dn->get_remote_ino() == ino);
} else {
}
else if (icode == 'I') {
// inode
- decode_import_inode(dn, bl, off, oldauth, imported_client_map, ls);
+ decode_import_inode(dn, blp, oldauth, imported_client_map, ls);
}
// add dentry to journal entry
void maybe_do_queued_export();
void encode_export_inode(CInode *in, bufferlist& enc_state,
- map<int,entity_inst_t>& exported_client_map,
- utime_t now);
- void finish_export_inode(CInode *in, list<Context*>& finished);
- int encode_export_dir(list<bufferlist>& dirstatelist,
+ map<int,entity_inst_t>& exported_client_map);
+ void finish_export_inode(CInode *in, utime_t now, list<Context*>& finished);
+ int encode_export_dir(bufferlist& exportbl,
CDir *dir,
map<int,entity_inst_t>& exported_client_map,
utime_t now);
void handle_export_dir(MExportDir *m);
public:
- void decode_import_inode(CDentry *dn, bufferlist& bl, int &off, int oldauth,
+ void decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int oldauth,
map<int,entity_inst_t>& imported_client_map,
LogSegment *ls);
- int decode_import_dir(bufferlist& bl,
+ int decode_import_dir(bufferlist::iterator& blp,
int oldauth,
CDir *import_root,
EImportStart *le,
// srcdn inode import?
if (!srcdn->is_auth() && destdn->is_auth()) {
assert(mdr->inode_import.length() > 0);
- int off = 0;
+ bufferlist::iterator blp = mdr->inode_import.begin();
map<int,entity_inst_t> imported_client_map;
- ::_decode(imported_client_map, mdr->inode_import, off);
- mdcache->migrator->decode_import_inode(destdn, mdr->inode_import, off,
+ ::_decode_simple(imported_client_map, blp);
+ mdcache->migrator->decode_import_inode(destdn, blp,
srcdn->authority().first,
imported_client_map,
mdr->ls);
map<int,entity_inst_t> exported_client_map;
bufferlist inodebl;
mdcache->migrator->encode_export_inode(srcdn->inode, inodebl,
- exported_client_map,
- mdr->now);
- mdcache->migrator->finish_export_inode(srcdn->inode, finished);
+ exported_client_map);
+ mdcache->migrator->finish_export_inode(srcdn->inode, mdr->now, finished);
mds->queue_waiters(finished); // this includes SINGLEAUTH waiters.
::_encode(exported_client_map, reply->inode_export);
reply->inode_export.claim_append(inodebl);
// encode/decode
void _encode(bufferlist& bl) {
- ::_encode(state, bl);
- ::_encode(gather_set, bl);
+ ::_encode_simple(state, bl);
+ ::_encode_simple(gather_set, bl);
}
- void _decode(bufferlist& bl, int& off) {
- ::_decode(state, bl, off);
- ::_decode(gather_set, bl, off);
+ void _decode(bufferlist::iterator& p) {
+ ::_decode_simple(state, p);
+ ::_decode_simple(gather_set, p);
}
class MExportDir : public Message {
dirfrag_t dirfrag;
- list<bufferlist> dirstate; // a bl for reach dir
- list<dirfrag_t> bounds;
+ bufferlist dirstate;
+ list<dirfrag_t> bounds;
public:
MExportDir() {}
}
dirfrag_t get_dirfrag() { return dirfrag; }
- list<bufferlist>& get_dirstate() { return dirstate; }
+ bufferlist& get_dirstate() { return dirstate; }
list<dirfrag_t>& get_bounds() { return bounds; }
- void add_dir(bufferlist& dir) {
- dirstate.push_back(dir);
- }
- void set_dirstate(const list<bufferlist>& ls) {
- dirstate = ls;
- }
- void take_dirstate(list<bufferlist>& ls) {
- dirstate.swap(ls);
+ void take_dirstate(bufferlist& bl) {
+ dirstate.claim(bl);
}
void add_export(dirfrag_t df) {
bounds.push_back(df);