}
}
+ int issue = 0;
if (!no_caps && cap) {
int likes = get_caps_liked();
int allowed = get_caps_allowed_for_client(session, file_i);
- int issue = (cap->wanted() | likes) & allowed;
+ issue = (cap->wanted() | likes) & allowed;
cap->issue_norevoke(issue);
issue = cap->pending();
+ dout(10) << "encode_inodestat issuing " << ccap_string(issue)
+ << " seq " << cap->get_last_seq() << dendl;
+ } else if (cap && cap->is_new() && !dir_realm) {
+ // alway issue new caps to client, otherwise the caps get lost
+ assert(cap->is_stale());
+ issue = cap->pending() | CEPH_CAP_PIN;
+ cap->issue_norevoke(issue);
+ dout(10) << "encode_inodestat issuing " << ccap_string(issue)
+ << " seq " << cap->get_last_seq()
+ << "(stale|new caps)" << dendl;
+ }
+
+ if (issue) {
cap->set_last_issue();
cap->set_last_issue_stamp(ceph_clock_now());
cap->clear_new();
ecap.wanted = cap->wanted();
ecap.cap_id = cap->get_cap_id();
ecap.seq = cap->get_last_seq();
- dout(10) << "encode_inodestat issuing " << ccap_string(issue)
- << " seq " << cap->get_last_seq() << dendl;
ecap.mseq = cap->get_mseq();
ecap.realm = realm->inode->ino();
} else {
- if (cap)
- cap->clear_new();
ecap.cap_id = 0;
ecap.caps = 0;
ecap.seq = 0;
const static unsigned STATE_STALE = (1<<0);
const static unsigned STATE_NEW = (1<<1);
+ const static unsigned STATE_IMPORTING = (1<<2);
Capability(CInode *i = NULL, uint64_t id = 0, client_t c = 0) :
bool is_new() { return state & STATE_NEW; }
void mark_new() { state |= STATE_NEW; }
void clear_new() { state &= ~STATE_NEW; }
+ bool is_importing() { return state & STATE_IMPORTING; }
+ void mark_importing() { state |= STATE_IMPORTING; }
+ void clear_importing() { state &= ~STATE_IMPORTING; }
CInode *get_inode() { return inode; }
client_t get_client() const { return client; }
++q) {
Capability *cap = in->get_client_cap(q->first);
assert(cap);
- if (cap->is_new())
+ if (cap->is_importing())
in->remove_client_cap(q->first);
}
in->put(CInode::PIN_IMPORTINGCAPS);
Capability *cap = in->get_client_cap(q->first);
assert(cap);
cap->merge(q->second, true);
+ cap->clear_importing();
mds->mdcache->do_cap_import(session, in, cap, q->second.cap_id, q->second.seq,
q->second.mseq - 1, it->second.peer, CEPH_CAP_FLAG_AUTH);
}
if (!cap) {
cap = in->add_client_cap(it->first, session);
if (peer < 0)
- cap->mark_new();
+ cap->mark_importing();
}
Capability::Import& im = import_map[it->first];