]> git.proxmox.com Git - ceph.git/blob - ceph/src/osd/Session.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / osd / Session.cc
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 }