1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "MissingLoc.h"
6 #define dout_context cct
8 #define dout_prefix (gen_prefix(*_dout))
9 #define dout_subsys ceph_subsys_osd
13 bool MissingLoc::readable_with_acting(
14 const hobject_t
&hoid
,
15 const set
<pg_shard_t
> &acting
,
16 eversion_t
* v
) const {
17 if (!needs_recovery(hoid
, v
))
21 auto missing_loc_entry
= missing_loc
.find(hoid
);
22 if (missing_loc_entry
== missing_loc
.end())
24 const set
<pg_shard_t
> &locs
= missing_loc_entry
->second
;
25 ldout(cct
, 10) << __func__
<< ": locs:" << locs
<< dendl
;
26 set
<pg_shard_t
> have_acting
;
27 for (auto i
= locs
.begin(); i
!= locs
.end(); ++i
) {
29 have_acting
.insert(*i
);
31 return (*is_readable
)(have_acting
);
34 void MissingLoc::add_batch_sources_info(
35 const set
<pg_shard_t
> &sources
,
38 ldout(cct
, 10) << __func__
<< ": adding sources in batch "
39 << sources
.size() << dendl
;
41 bool sources_updated
= false;
42 for (auto i
= needs_recovery_map
.begin();
43 i
!= needs_recovery_map
.end();
45 if (handle
&& ++loop
>= cct
->_conf
->osd_loop_before_reset_tphandle
) {
46 handle
->reset_tp_timeout();
49 if (i
->second
.is_delete())
52 auto p
= missing_loc
.find(i
->first
);
53 if (p
== missing_loc
.end()) {
54 p
= missing_loc
.emplace(i
->first
, set
<pg_shard_t
>()).first
;
56 _dec_count(p
->second
);
58 missing_loc
[i
->first
].insert(sources
.begin(), sources
.end());
59 _inc_count(p
->second
);
61 if (!sources_updated
) {
62 missing_loc_sources
.insert(sources
.begin(), sources
.end());
63 sources_updated
= true;
68 bool MissingLoc::add_source_info(
70 const pg_info_t
&oinfo
,
71 const pg_missing_t
&omissing
,
74 bool found_missing
= false;
76 bool sources_updated
= false;
78 for (auto p
= needs_recovery_map
.begin();
79 p
!= needs_recovery_map
.end();
81 const hobject_t
&soid(p
->first
);
82 eversion_t need
= p
->second
.need
;
83 if (handle
&& ++loop
>= cct
->_conf
->osd_loop_before_reset_tphandle
) {
84 handle
->reset_tp_timeout();
87 if (p
->second
.is_delete()) {
88 ldout(cct
, 10) << __func__
<< " " << soid
89 << " delete, ignoring source" << dendl
;
92 if (oinfo
.last_update
< need
) {
93 ldout(cct
, 10) << "search_for_missing " << soid
<< " " << need
94 << " also missing on osd." << fromosd
95 << " (last_update " << oinfo
.last_update
96 << " < needed " << need
<< ")" << dendl
;
99 if (p
->first
>= oinfo
.last_backfill
) {
100 // FIXME: this is _probably_ true, although it could conceivably
101 // be in the undefined region! Hmm!
102 ldout(cct
, 10) << "search_for_missing " << soid
<< " " << need
103 << " also missing on osd." << fromosd
104 << " (past last_backfill " << oinfo
.last_backfill
108 if (omissing
.is_missing(soid
)) {
109 ldout(cct
, 10) << "search_for_missing " << soid
<< " " << need
110 << " also missing on osd." << fromosd
<< dendl
;
114 ldout(cct
, 10) << "search_for_missing " << soid
<< " " << need
115 << " is on osd." << fromosd
<< dendl
;
118 auto p
= missing_loc
.find(soid
);
119 if (p
== missing_loc
.end()) {
120 p
= missing_loc
.emplace(soid
, set
<pg_shard_t
>()).first
;
122 _dec_count(p
->second
);
124 p
->second
.insert(fromosd
);
125 _inc_count(p
->second
);
128 if (!sources_updated
) {
129 missing_loc_sources
.insert(fromosd
);
130 sources_updated
= true;
132 found_missing
= true;
135 ldout(cct
, 20) << "needs_recovery_map missing " << needs_recovery_map
137 return found_missing
;
140 void MissingLoc::check_recovery_sources(const OSDMapRef
& osdmap
)
142 set
<pg_shard_t
> now_down
;
143 for (auto p
= missing_loc_sources
.begin();
144 p
!= missing_loc_sources
.end();
146 if (osdmap
->is_up(p
->osd
)) {
150 ldout(cct
, 10) << __func__
<< " source osd." << *p
<< " now down" << dendl
;
152 missing_loc_sources
.erase(p
++);
155 if (now_down
.empty()) {
156 ldout(cct
, 10) << __func__
<< " no source osds (" << missing_loc_sources
<< ") went down" << dendl
;
158 ldout(cct
, 10) << __func__
<< " sources osds " << now_down
<< " now down, remaining sources are "
159 << missing_loc_sources
<< dendl
;
161 // filter missing_loc
162 auto p
= missing_loc
.begin();
163 while (p
!= missing_loc
.end()) {
164 auto q
= p
->second
.begin();
165 bool changed
= false;
166 while (q
!= p
->second
.end()) {
167 if (now_down
.count(*q
)) {
170 _dec_count(p
->second
);
172 p
->second
.erase(q
++);
177 if (p
->second
.empty()) {
178 missing_loc
.erase(p
++);
181 _inc_count(p
->second
);
189 void MissingLoc::remove_stray_recovery_sources(pg_shard_t stray
)
191 ldout(cct
, 10) << __func__
<< " remove osd " << stray
<< " from missing_loc" << dendl
;
192 // filter missing_loc
193 auto p
= missing_loc
.begin();
194 while (p
!= missing_loc
.end()) {
195 auto q
= p
->second
.begin();
196 bool changed
= false;
197 while (q
!= p
->second
.end()) {
201 _dec_count(p
->second
);
203 p
->second
.erase(q
++);
208 if (p
->second
.empty()) {
209 missing_loc
.erase(p
++);
212 _inc_count(p
->second
);
217 // filter missing_loc_sources
218 for (auto p
= missing_loc_sources
.begin(); p
!= missing_loc_sources
.end();) {
223 ldout(cct
, 10) << __func__
<< " remove osd" << stray
<< " from missing_loc_sources" << dendl
;
224 missing_loc_sources
.erase(p
++);