{
dout(10) << "split_need_snapflush [" << cowin->first << "," << cowin->last << "] for " << *cowin << dendl;
for (compact_map<snapid_t, set<client_t> >::iterator p = client_need_snapflush.lower_bound(cowin->first);
- p != client_need_snapflush.end() && p->first <= cowin->last;
- ++p) {
- assert(!p->second.empty());
- cowin->auth_pin(this);
+ p != client_need_snapflush.end() && p->first < in->first; ) {
+ compact_map<snapid_t, set<client_t> >::iterator q = p;
+ ++p;
+ assert(!q->second.empty());
+ if (cowin->last >= q->first)
+ cowin->auth_pin(this);
+ else
+ client_need_snapflush.erase(q);
in->auth_unpin(this);
}
}
{
assert(last >= in->first);
- CInode *oldin = new CInode(this, true, in->first, last);
+ SnapRealm *realm = in->find_snaprealm();
+ const set<snapid_t>& snaps = realm->get_snaps();
+
+ // make sure snap inode's last match existing snapshots.
+ // MDCache::pick_inode_snap() requires this.
+ snapid_t last_snap = last;
+ if (snaps.count(last) == 0) {
+ set<snapid_t>::const_iterator p = snaps.upper_bound(last);
+ if (p != snaps.begin()) {
+ --p;
+ if (*p >= in->first)
+ last_snap = *p;
+ }
+ }
+
+ CInode *oldin = new CInode(this, true, in->first, last_snap);
oldin->inode = *in->get_previous_projected_inode();
oldin->symlink = in->symlink;
oldin->xattrs = *in->get_previous_projected_xattrs();
-
oldin->inode.trim_client_ranges(last);
if (in->first < in->oldest_snap)
dout(10) << "cow_inode " << *in << " to " << *oldin << dendl;
add_inode(oldin);
-
- SnapRealm *realm = in->find_snaprealm();
- const set<snapid_t>& snaps = realm->get_snaps();
if (in->last != CEPH_NOSNAP) {
CInode *head_in = get_inode(in->ino());