From: Sage Weil Date: Mon, 4 Aug 2008 17:38:17 +0000 (-0700) Subject: mds: list child snaprealms in split, and send split notifications to all clients... X-Git-Tag: v0.4~328 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=44eeb6a9e6208fd1b3b28c0949a778516b97bca8;p=ceph.git mds: list child snaprealms in split, and send split notifications to all clients with caps in nested snaprealms --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 73d598753f3..837e4eab454 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -3552,6 +3552,12 @@ void MDCache::prepare_realm_split(SnapRealm *realm, int client, inodeno_t ino, splits[client] = snap = new MClientSnap(CEPH_SNAP_OP_SPLIT); snap->split = realm->inode->ino(); realm->build_snap_trace(snap->bl); + + for (set::iterator p = realm->open_children.begin(); + p != realm->open_children.end(); + p++) + snap->split_realms.push_back((*p)->inode->ino()); + } else snap = splits[client]; snap->split_inos.push_back(ino); @@ -3567,7 +3573,7 @@ void MDCache::send_realm_splits(map& splits) Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(p->first)); if (session) { dout(10) << " client" << p->first << " split " << p->second->split - << " inos " << p->second->split_inos << dendl; + << " inos " << p->second->split_inos << dendl; mds->send_message_client(p->second, session->inst); } else { dout(10) << " no session for client" << p->first << dendl; @@ -6134,28 +6140,49 @@ void MDCache::_snaprealm_create_finish(MDRequest *mdr, Mutation *mut, CInode *in list split_inos; for (xlist::iterator p = in->snaprealm->inodes_with_caps.begin(); !p.end(); ++p) split_inos.push_back((*p)->ino()); + + list split_realms; + for (set::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); const vector snaps = in->snaprealm->get_snap_vector(); map updates; - for (map >::iterator p = in->snaprealm->client_caps.begin(); - p != in->snaprealm->client_caps.end(); - p++) { - assert(!p->second.empty()); - MClientSnap *update = updates[p->first] = new MClientSnap(CEPH_SNAP_OP_SPLIT); - update->split = in->ino(); - update->split_inos = split_inos; - update->bl = snapbl; - updates[p->first] = update; + + // send splits for all clients with caps in this _or nested_ realms. + list q; + q.push_back(in->snaprealm); + while (!q.empty()) { + SnapRealm *realm = q.front(); + q.pop_front(); + + for (map >::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->split = in->ino(); + update->split_inos = split_inos; + update->split_realms = split_realms; + update->bl = snapbl; + updates[p->first] = update; + } + + for (set::iterator p = realm->open_children.begin(); + p != realm->open_children.end(); + p++) + q.push_back(*p); } - // send - for (map::iterator p = updates.begin(); - p != updates.end(); - p++) - mds->send_message_client(p->second, p->first); + send_realm_splits(updates); + + static int count = 5; + if (--count == 0) + assert(0); // hack test test ********** // done. mdr->more()->stid = 0; // caller will likely need to reuse this