}
-void MDCache::do_realm_split_notify(CInode *in)
+void MDCache::do_realm_invalidate_and_update_notify(CInode *in, int snapop)
{
- dout(10) << "do_realm_split_notify " << *in->snaprealm << " " << *in << dendl;
-
- // notify clients of update|split
- vector<inodeno_t> split_inos;
- for (xlist<CInode*>::iterator p = in->snaprealm->inodes_with_caps.begin(); !p.end(); ++p)
- split_inos.push_back((*p)->ino());
+ dout(10) << "do_realm_invalidate_and_update_notify " << *in->snaprealm << " " << *in << dendl;
+ vector<inodeno_t> split_inos;
vector<inodeno_t> split_realms;
- for (set<SnapRealm*>::iterator p = in->snaprealm->open_children.begin();
- p != in->snaprealm->open_children.end();
- p++)
- split_realms.push_back((*p)->inode->ino());
-
- bufferlist snapbl;
- in->snaprealm->build_snap_trace(snapbl);
-
- map<int, MClientSnap*> updates;
-
- // send splits for all clients with caps in this _or nested_ realms.
- list<SnapRealm*> q;
- q.push_back(in->snaprealm);
- while (!q.empty()) {
- SnapRealm *realm = q.front();
- q.pop_front();
- for (map<int, xlist<Capability*> >::iterator p = realm->client_caps.begin();
- p != realm->client_caps.end();
- p++) {
- assert(!p->second.empty());
- MClientSnap *update = updates[p->first] = new MClientSnap(CEPH_SNAP_OP_SPLIT);
- update->head.split = in->ino();
- update->split_inos = split_inos;
- update->split_realms = split_realms;
- update->bl = snapbl;
- updates[p->first] = update;
- }
-
- for (set<SnapRealm*>::iterator p = realm->open_children.begin();
- p != realm->open_children.end();
+ if (snapop == CEPH_SNAP_OP_SPLIT) {
+ // notify clients of update|split
+ for (xlist<CInode*>::iterator p = in->snaprealm->inodes_with_caps.begin(); !p.end(); ++p)
+ split_inos.push_back((*p)->ino());
+
+ for (set<SnapRealm*>::iterator p = in->snaprealm->open_children.begin();
+ p != in->snaprealm->open_children.end();
p++)
- q.push_back(*p);
+ split_realms.push_back((*p)->inode->ino());
}
-
- send_snaps(updates);
-}
-
-void MDCache::do_realm_invalidate_and_update_notify(CInode *in, int snapop)
-{
- dout(10) << "do_realm_invalidate_and_update_notify " << *in->snaprealm << " " << *in << dendl;
bufferlist snapbl;
in->snaprealm->build_snap_trace(snapbl);
SnapRealm *realm = q.front();
q.pop_front();
- dout(10) << " realm " << *realm
- << " on " << *realm->inode << dendl;
+ dout(10) << " realm " << *realm << " on " << *realm->inode << dendl;
realm->invalidate_cached_snaps();
for (map<int, xlist<Capability*> >::iterator p = realm->client_caps.begin();
p++) {
assert(!p->second.empty());
if (updates.count(p->first) == 0) {
- MClientSnap *update = updates[p->first] = new MClientSnap(snapop);
+ MClientSnap *update = new MClientSnap(snapop);
+ update->head.split = in->ino();
+ update->split_inos = split_inos;
+ update->split_realms = split_realms;
update->bl = snapbl;
+ updates[p->first] = update;
}
}
in->open_snaprealm();
in->snaprealm->seq = in->snaprealm->created = seq;
- do_realm_split_notify(in);
+ do_realm_invalidate_and_update_notify(in, CEPH_SNAP_OP_SPLIT);
/*
static int count = 5;
void process_reconnected_caps();
void prepare_realm_split(SnapRealm *realm, int client, inodeno_t ino,
map<int,MClientSnap*>& splits);
- void do_realm_split_notify(CInode *in);
void do_realm_invalidate_and_update_notify(CInode *in, int snapop);
void send_snaps(map<int,MClientSnap*>& splits);
void rejoin_import_cap(CInode *in, int client, ceph_mds_cap_reconnect& icr, int frommds);
}
straydn->inode->snaprealm->add_past_parent(oldparent);
if (isnew)
- mdcache->do_realm_split_notify(straydn->inode);
+ mdcache->do_realm_invalidate_and_update_notify(straydn->inode, CEPH_SNAP_OP_SPLIT);
}
dn->mark_dirty(dnpv, mdr->ls);
if (mdr->now == utime_t())
mdr->now = g_clock.now();
-
- // create snaprealm?
- if (!diri->snaprealm) {
- mds->mdcache->snaprealm_create(mdr, diri);
- return;
- }
-
// allocate a snapid
if (!mdr->more()->stid) {
// prepare an stid
// project the snaprealm.. hack!
bufferlist snapbl;
+ bool newrealm = false;
+ if (!diri->snaprealm) {
+ newrealm = true;
+ diri->open_snaprealm(true);
+ diri->snaprealm->created = snapid;
+ }
snapid_t old_seq = diri->snaprealm->seq;
snapid_t old_lc = diri->snaprealm->last_created;
diri->snaprealm->snaps[snapid] = info;
diri->snaprealm->snaps.erase(snapid);
diri->snaprealm->seq = old_seq;
diri->snaprealm->last_created = old_lc;
+ if (newrealm)
+ diri->close_snaprealm(true);
+
le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), true, 0, pi, 0, &snapbl);
mdlog->submit_entry(le, new C_MDS_mksnap_finish(mds, mdr, diri, info));
// create snap
snapid_t snapid = info.snapid;
+ int op = CEPH_SNAP_OP_CREATE;
+ if (!diri->snaprealm) {
+ diri->open_snaprealm();
+ diri->snaprealm->created = snapid;
+ op = CEPH_SNAP_OP_SPLIT;
+ }
diri->snaprealm->snaps[snapid] = info;
diri->snaprealm->seq = snapid;
diri->snaprealm->last_created = snapid;
dout(10) << "snaprealm now " << *diri->snaprealm << dendl;
- mdcache->do_realm_invalidate_and_update_notify(diri, CEPH_SNAP_OP_CREATE);
+ mdcache->do_realm_invalidate_and_update_notify(diri, op);
// yay
mdr->ref = diri;