CEPH_OSD_FLAG_ENFORCE_SNAPC),
NULL,
NULL /* no callback, we'll rely on the ordering w.r.t the next op */);
- osd->objecter_lock.Unlock();
+
+ // do we need to send the second delete?
+ SnapContext dsnapc2;
+ vector<snapid_t>::reverse_iterator rp = snapset.snaps.rbegin();
+
+ // advance rp to the smallest snap not contained by the last flushed clone
+ while (rp != snapset.snaps.rend() && *rp <= dsnapc.seq)
+ ++rp;
+
+ // set dnsnapc2.seq to be the snap prior to that snap (the object did not
+ // exist at *rq, so it must have been deleted prior to that).
+ dsnapc2.seq = (rp == snapset.snaps.rend()) ? snapset.seq : *rp;
+ if (dsnapc2.seq > 0)
+ dsnapc2.seq.val -= 1;
+
+ if (dsnapc2.seq != dsnapc.seq) {
+ dsnapc2.snaps = dsnapc.snaps;
+
+ ObjectOperation o2;
+ o2.remove();
- osd->objecter_lock.Lock();
+ osd->objecter->mutate(
+ soid.oid,
+ base_oloc,
+ o2,
+ dsnapc2,
+ oi.mtime,
+ (CEPH_OSD_FLAG_IGNORE_OVERLAY |
+ CEPH_OSD_FLAG_ORDERSNAP |
+ CEPH_OSD_FLAG_ENFORCE_SNAPC),
+ NULL,
+ NULL /* no callback, we'll rely on the ordering w.r.t the next op */);
- osd->objecter_lock.Unlock();
+ }
}
FlushOpRef fop(new FlushOp);