]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "PG.h" | |
5 | #include "Session.h" | |
6 | ||
7 | #include "common/debug.h" | |
8 | ||
9 | #define dout_context cct | |
10 | #define dout_subsys ceph_subsys_osd | |
11 | ||
12 | void Session::clear_backoffs() | |
13 | { | |
14 | map<spg_t,map<hobject_t,set<BackoffRef>>> ls; | |
15 | { | |
16 | Mutex::Locker l(backoff_lock); | |
17 | ls.swap(backoffs); | |
18 | backoff_count = 0; | |
19 | } | |
20 | for (auto& i : ls) { | |
21 | for (auto& p : i.second) { | |
22 | for (auto& b : p.second) { | |
23 | Mutex::Locker l(b->lock); | |
24 | if (b->pg) { | |
25 | assert(b->session == this); | |
26 | assert(b->is_new() || b->is_acked()); | |
27 | b->pg->rm_backoff(b); | |
28 | b->pg.reset(); | |
29 | b->session.reset(); | |
30 | } else if (b->session) { | |
31 | assert(b->session == this); | |
32 | assert(b->is_deleting()); | |
33 | b->session.reset(); | |
34 | } | |
35 | } | |
36 | } | |
37 | } | |
38 | } | |
39 | ||
40 | void Session::ack_backoff( | |
41 | CephContext *cct, | |
42 | spg_t pgid, | |
43 | uint64_t id, | |
44 | const hobject_t& begin, | |
45 | const hobject_t& end) | |
46 | { | |
47 | Mutex::Locker l(backoff_lock); | |
48 | auto p = backoffs.find(pgid); | |
49 | if (p == backoffs.end()) { | |
50 | dout(20) << __func__ << " " << pgid << " " << id << " [" << begin << "," | |
51 | << end << ") pg not found" << dendl; | |
52 | return; | |
53 | } | |
54 | auto q = p->second.find(begin); | |
55 | if (q == p->second.end()) { | |
56 | dout(20) << __func__ << " " << pgid << " " << id << " [" << begin << "," | |
57 | << end << ") begin not found" << dendl; | |
58 | return; | |
59 | } | |
60 | for (auto i = q->second.begin(); i != q->second.end(); ++i) { | |
61 | Backoff *b = (*i).get(); | |
62 | if (b->id == id) { | |
63 | if (b->is_new()) { | |
64 | b->state = Backoff::STATE_ACKED; | |
65 | dout(20) << __func__ << " now " << *b << dendl; | |
66 | } else if (b->is_deleting()) { | |
67 | dout(20) << __func__ << " deleting " << *b << dendl; | |
68 | q->second.erase(i); | |
69 | --backoff_count; | |
70 | } | |
71 | break; | |
72 | } | |
73 | } | |
74 | if (q->second.empty()) { | |
75 | dout(20) << __func__ << " clearing begin bin " << q->first << dendl; | |
76 | p->second.erase(q); | |
77 | if (p->second.empty()) { | |
78 | dout(20) << __func__ << " clearing pg bin " << p->first << dendl; | |
79 | backoffs.erase(p); | |
80 | } | |
81 | } | |
82 | assert(!backoff_count == backoffs.empty()); | |
83 | } | |
84 | ||
85 | bool Session::check_backoff( | |
86 | CephContext *cct, spg_t pgid, const hobject_t& oid, const Message *m) | |
87 | { | |
88 | BackoffRef b(have_backoff(pgid, oid)); | |
89 | if (b) { | |
90 | dout(10) << __func__ << " session " << this << " has backoff " << *b | |
91 | << " for " << *m << dendl; | |
92 | assert(!b->is_acked() || !g_conf->osd_debug_crash_on_ignored_backoff); | |
93 | return true; | |
94 | } | |
95 | // we may race with ms_handle_reset. it clears session->con before removing | |
96 | // backoffs, so if we see con is cleared here we have to abort this | |
97 | // request. | |
98 | if (!con) { | |
99 | dout(10) << __func__ << " session " << this << " disconnected" << dendl; | |
100 | return true; | |
101 | } | |
102 | return false; | |
103 | } |