Two fixes:
* Client would unlink everything it could, instead of just
meeting its goal, because caps.size() doesn't change until
dentries are cleaned up later. Take account of the trimmed
count in the while() condition to fix that.
* Don't count the root ino as trimmed, as although it has no
dentries (of course), we will never give up the cap.
With this change, the client will now precisely achieve the number
of caps requested in CEPH_SESSION_RECALL_STATE messages.
Signed-off-by: John Spray <john.spray@redhat.com>
int trimmed = 0;
xlist<Cap*>::iterator p = s->caps.begin();
- while (s->caps.size() > max && !p.end()) {
+ while ((s->caps.size() - trimmed) > max && !p.end()) {
Cap *cap = *p;
s->s_cap_iterator = cap;
Inode *in = cap->inode;
+
if (in->caps.size() > 1 && cap != in->auth_cap) {
int mine = cap->issued | cap->implemented;
int oissued = in->auth_cap ? in->auth_cap->issued : 0;
all = false;
}
}
- if (all)
+ if (all && in->ino != MDS_INO_ROOT) {
+ ldout(cct, 20) << __func__ << " counting as trimmed: " << *in << dendl;
trimmed++;
+ }
}
++p;