}
/*
- * Flush all caps back to the MDS. Because the callers generally wait on the
- * result of this function (syncfs and umount cases), we set
- * CHECK_CAPS_SYNCHRONOUS on the last check_caps call.
+ * Flush all the dirty caps back to the MDS. Because the callers
+ * generally wait on the result of this function (syncfs and umount
+ * cases), we set CHECK_CAPS_SYNCHRONOUS on the last check_caps call.
*/
void Client::flush_caps_sync()
{
ldout(cct, 10) << __func__ << dendl;
- xlist<Inode*>::iterator p = delayed_list.begin();
- while (!p.end()) {
- unsigned flags = CHECK_CAPS_NODELAY;
- Inode *in = *p;
-
- ++p;
- delayed_list.pop_front();
- if (p.end() && dirty_list.empty())
- flags |= CHECK_CAPS_SYNCHRONOUS;
- check_caps(in, flags);
- }
-
- // other caps, too
- p = dirty_list.begin();
- while (!p.end()) {
- unsigned flags = CHECK_CAPS_NODELAY;
- Inode *in = *p;
+ for (auto &q : mds_sessions) {
+ auto s = q.second;
+ xlist<Inode*>::iterator p = s->dirty_list.begin();
+ while (!p.end()) {
+ unsigned flags = CHECK_CAPS_NODELAY;
+ Inode *in = *p;
- ++p;
- if (p.end())
- flags |= CHECK_CAPS_SYNCHRONOUS;
- check_caps(in, flags);
+ ++p;
+ if (p.end())
+ flags |= CHECK_CAPS_SYNCHRONOUS;
+ check_caps(in, flags);
+ }
}
}
}
if (abort || blocklisted) {
- for (auto p = dirty_list.begin(); !p.end(); ) {
- Inode *in = *p;
- ++p;
- if (in->dirty_caps) {
- ldout(cct, 0) << " drop dirty caps on " << *in << dendl;
- in->mark_caps_clean();
- put_inode(in);
+ for (auto &q : mds_sessions) {
+ auto s = q.second;
+ for (auto p = s->dirty_list.begin(); !p.end(); ) {
+ Inode *in = *p;
+ ++p;
+ if (in->dirty_caps) {
+ ldout(cct, 0) << " drop dirty caps on " << *in << dendl;
+ in->mark_caps_clean();
+ put_inode(in);
+ }
}
}
} else {
return std::make_pair(opened_inodes, inode_map.size());
}
- xlist<Inode*> &get_dirty_list() { return dirty_list; }
-
/* timer_lock for 'timer' */
ceph::mutex timer_lock = ceph::make_mutex("Client::timer_lock");
SafeTimer timer;
// cap flushing
ceph_tid_t last_flush_tid = 1;
- // dirty_list keeps all the dirty inodes before flushing.
- xlist<Inode*> delayed_list, dirty_list;
+ xlist<Inode*> delayed_list;
int num_flushing_caps = 0;
ceph::unordered_map<inodeno_t,SnapRealm*> snap_realms;
std::map<std::string, std::string> metadata;
*/
void Inode::mark_caps_dirty(int caps)
{
+ /*
+ * If auth_cap is nullptr means the reonnecting is not finished or
+ * already rejected.
+ */
+ if (!auth_cap) {
+ ceph_assert(!dirty_caps);
+
+ lsubdout(client->cct, client, 1) << __func__ << " " << *this << " dirty caps '" << ccap_string(caps)
+ << "', but no auth cap." << dendl;
+ return;
+ }
+
lsubdout(client->cct, client, 10) << __func__ << " " << *this << " " << ccap_string(dirty_caps) << " -> "
<< ccap_string(dirty_caps | caps) << dendl;
+
if (caps && !caps_dirty())
iget();
+
dirty_caps |= caps;
- client->get_dirty_list().push_back(&dirty_cap_item);
+ auth_cap->session->get_dirty_list().push_back(&dirty_cap_item);
client->cap_delay_requeue(this);
}
std::list<Context*> waiting_for_open;
xlist<Cap*> caps;
+ // dirty_list keeps all the dirty inodes before flushing in current session.
+ xlist<Inode*> dirty_list;
xlist<Inode*> flushing_caps;
xlist<MetaRequest*> requests;
xlist<MetaRequest*> unsafe_requests;
: mds_num(mds_num), con(con), addrs(addrs) {
}
+ xlist<Inode*> &get_dirty_list() { return dirty_list; }
+
const char *get_state_name() const;
void dump(Formatter *f, bool cap_dump=false) const;