}
in->flushing_caps |= flush;
in->dirty_caps = 0;
- flush_tid = in->flushing_cap_tid = ++last_flush_tid;
+ flush_tid = ++last_flush_tid;
+ //set the tid for each cap we're flushing
+ for (int i = 0; i < CEPH_CAP_BITS; ++i) {
+ if (flush & (1<<i))
+ in->flushing_cap_tid[i] = flush_tid;
+ }
dout(10) << " flushing " << ccap_string(flush) << dendl;
}
dout(20) << " reflushing caps on " << *in << " to mds" << mds << dendl;
InodeCap *cap = in->auth_cap;
assert(cap->session == session);
- send_cap(in, mds, cap, in->caps_used(), in->caps_wanted(),
- cap->issued | cap->implemented,
- in->flushing_caps, in->flushing_cap_tid);
+ //ugh, it's a lot of comparisons to push the caps on same tid out together
+ int flush_now;
+ int already_flushed = 0;
+ for (int i=0; i<CEPH_CAP_BITS; ++i) {
+ if ((in->flushing_caps & 1<<i) &&
+ !(already_flushed & 1<<i)) {
+ flush_now = 0;
+ flush_now |= 1<<i;
+ for (int j=i+1; j<CEPH_CAP_BITS; ++j) {
+ if ((in->flushing_caps & 1<<j) &&
+ ( in->flushing_cap_tid[j] == in->flushing_cap_tid[i]))
+ flush_now |= 1<<j;
+ }
+ send_cap(in, mds, cap, in->caps_used(), in->caps_wanted(),
+ cap->issued | cap->implemented,
+ flush_now, in->flushing_cap_tid[i]);
+ }
+ }
}
}
void Client::handle_cap_flush_ack(Inode *in, int mds, InodeCap *cap, MClientCaps *m)
{
- int cleaned = m->get_dirty();
+ int dirty = m->get_dirty();
+ int cleaned = 0;
+ for (int i = 0; i < CEPH_CAP_BITS; ++i) {
+ if ((dirty & (1 << i)) &&
+ (m->get_client_tid() == in->flushing_cap_tid[i]))
+ cleaned |= 1 << i;
+ }
+
dout(5) << "handle_cap_flush_ack mds" << mds
- << " cleaned " << ccap_string(cleaned) << " on " << *in << dendl;
+ << " cleaned " << ccap_string(cleaned) << " on " << *in
+ << " with " << ccap_string(dirty) << dendl;
+
- if (m->get_client_tid() != in->flushing_cap_tid) {
- dout(10) << " tid " << m->get_client_tid() << " != " << in->flushing_cap_tid << dendl;
+ if (!cleaned) {
+ dout(10) << " tid " << m->get_client_tid() << " != any cap bit tids" << dendl;
} else {
if (in->flushing_caps) {
dout(5) << " flushing_caps " << ccap_string(in->flushing_caps)
put_inode(in);
}
}
-
+
delete m;
}
map<int,InodeCap*> caps; // mds -> InodeCap
InodeCap *auth_cap;
unsigned dirty_caps, flushing_caps;
- __u64 flushing_cap_seq, flushing_cap_tid;
+ __u64 flushing_cap_seq;
+ __u16 flushing_cap_tid[CEPH_CAP_BITS];
int shared_gen, cache_gen;
int snap_caps, snap_cap_refs;
unsigned exporting_issued;
rdev(0), mode(0), uid(0), gid(0), nlink(0), size(0), truncate_seq(0), truncate_size(0), truncate_from(0),
time_warp_seq(0), max_size(0), version(0), xattr_version(0),
dir_auth(-1), dir_hashed(false), dir_replicated(false),
- dirty_caps(0), flushing_caps(0), flushing_cap_seq(0), flushing_cap_tid(0), shared_gen(0), cache_gen(0),
+ dirty_caps(0), flushing_caps(0), flushing_cap_seq(0), shared_gen(0), cache_gen(0),
snap_caps(0), snap_cap_refs(0),
exporting_issued(0), exporting_mds(-1), exporting_mseq(0),
cap_item(this), flushing_cap_item(this),
ref(0), ll_ref(0),
dir(0), dn(0),
hack_balance_reads(false)
- { }
+ {
+ memset(&flushing_cap_tid, 0, sizeof(__u16)*CEPH_CAP_BITS);
+ }
~Inode() { }
vinodeno_t vino() { return vinodeno_t(ino, snapid); }