+void CInode::add_need_snapflush(CInode *snapin, snapid_t snapid, client_t client)
+{
+ dout(10) << "add_need_snapflush client" << client << " snapid " << snapid << " on " << snapin << dendl;
+
+ if (client_need_snapflush.empty()) {
+ get(CInode::PIN_NEEDSNAPFLUSH);
+ }
+
+ set<client_t>& clients = client_need_snapflush[snapid];
+ clients.insert(client);
+}
+
+void CInode::remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t client)
+{
+ dout(10) << "remove_need_snapflush client" << client << " snapid " << snapid << " on " << snapin << dendl;
+ set<client_t>& clients = client_need_snapflush[snapid];
+ clients.erase(client);
+ if (clients.empty()) {
+ client_need_snapflush.erase(snapid);
+
+ if (client_need_snapflush.empty()) {
+ put(CInode::PIN_NEEDSNAPFLUSH);
+ }
+ }
+}
+
+
+
void CInode::mark_dirty_rstat()
{
if (!state_test(STATE_DIRTYRSTAT)) {
map<int, set<client_t> > client_snap_caps; // [auth] [snap] dirty metadata we still need from the head
public:
map<snapid_t, set<client_t> > client_need_snapflush;
+
+ void add_need_snapflush(CInode *snapin, snapid_t snapid, client_t client);
+ void remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t client);
+
protected:
ceph_lock_state_t fcntl_locks;
dout(10) << "_do_null_snapflish client" << client << " follows " << follows << " on " << *head_in << dendl;
map<snapid_t, set<client_t> >::iterator p = head_in->client_need_snapflush.begin();
while (p != head_in->client_need_snapflush.end()) {
- // p->first is the snap inode's ->last
- if (follows > p->first)
+ snapid_t snapid = p->first;
+ set<client_t>& clients = p->second;
+ p++;
+
+ // snapid is the snap inode's ->last
+ if (follows > snapid)
break;
- if (p->second.count(client)) {
- dout(10) << " doing async NULL snapflush on " << p->first << " from client" << p->second << dendl;
- CInode *sin = mdcache->get_inode(head_in->ino(), p->first);
+ if (clients.count(client)) {
+ dout(10) << " doing async NULL snapflush on " << snapid << " from client" << client << dendl;
+ CInode *sin = mdcache->get_inode(head_in->ino(), snapid);
if (!sin && head_in->is_multiversion())
sin = head_in;
assert(sin);
- _do_snap_update(sin, p->first, 0, sin->first - 1, client, NULL, NULL);
- head_in->client_need_snapflush[p->first].erase(client);
- if (head_in->client_need_snapflush[p->first].empty()) {
- head_in->client_need_snapflush.erase(p++);
- if (head_in->client_need_snapflush.empty())
- head_in->put(CInode::PIN_NEEDSNAPFLUSH);
- continue;
- }
+ _do_snap_update(sin, snapid, 0, sin->first - 1, client, NULL, NULL);
+ head_in->remove_need_snapflush(sin, snapid, client);
}
- p++;
}
}
_do_snap_update(in, snap, m->get_dirty(), follows, client, m, ack);
- if (in != head_in) {
- head_in->client_need_snapflush[snap].erase(client);
- if (head_in->client_need_snapflush[snap].empty()) {
- head_in->client_need_snapflush.erase(snap);
- if (head_in->client_need_snapflush.empty())
- head_in->put(CInode::PIN_NEEDSNAPFLUSH);
- }
- }
+ if (in != head_in)
+ head_in->remove_need_snapflush(in, snap, client);
} else
dout(7) << " not expecting flushsnap " << snap << " from client" << client << " on " << *in << dendl;
for (set<snapid_t>::const_iterator q = snaps.lower_bound(oldin->first);
q != snaps.end() && *q <= last;
q++) {
- dout(10) << " need_snapflush on " << *q << dendl;
- if (in->client_need_snapflush.empty())
- in->get(CInode::PIN_NEEDSNAPFLUSH);
- in->client_need_snapflush[*q].insert(client);
+ in->add_need_snapflush(oldin, *q, client);
}
} else {
dout(10) << " ignoring client" << client << " cap follows " << cap->client_follows << dendl;