Skip to content

Commit 9609410

Browse files
committed
osd: Make scrub determine the correct object size.
Signed-off-by: Alex Ainscow <[email protected]>
1 parent 0d689e9 commit 9609410

File tree

9 files changed

+58
-17
lines changed

9 files changed

+58
-17
lines changed

src/osd/ECBackend.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,12 @@ class ECBackend : public ECCommon {
373373
ScrubMap::object &o
374374
);
375375

376-
uint64_t be_get_ondisk_size(uint64_t logical_size, shard_id_t shard_id
377-
) const {
376+
uint64_t be_get_ondisk_size(uint64_t logical_size, shard_id_t shard_id,
377+
bool object_is_legacy_ec) const {
378+
if (object_is_legacy_ec) {
379+
// In legacy EC, all shards were padded to the next chunk boundry.
380+
return sinfo.ro_offset_to_next_chunk_offset(logical_size);
381+
}
378382
return object_size_to_shard_size(logical_size, shard_id);
379383
}
380384
};

src/osd/ECSwitch.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,11 @@ class ECSwitch : public PGBackend
293293
}
294294

295295
uint64_t be_get_ondisk_size(uint64_t logical_size,
296-
shard_id_t shard_id) const final {
296+
shard_id_t shard_id,
297+
bool object_is_legacy_ec) const final {
297298
if (is_optimized())
298299
{
299-
return optimized.be_get_ondisk_size(logical_size, shard_id);
300+
return optimized.be_get_ondisk_size(logical_size, shard_id, object_is_legacy_ec);
300301
}
301302
return legacy.be_get_ondisk_size(logical_size);
302303
}

src/osd/PG.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,8 +1414,9 @@ class PG : public DoutPrefixProvider,
14141414
}
14151415

14161416
uint64_t logical_to_ondisk_size(uint64_t logical_size,
1417-
shard_id_t shard_id) const final {
1418-
return get_pgbackend()->be_get_ondisk_size(logical_size, shard_id_t(shard_id));
1417+
shard_id_t shard_id,
1418+
bool object_is_legacy_ec) const final {
1419+
return get_pgbackend()->be_get_ondisk_size(logical_size, shard_id_t(shard_id), object_is_legacy_ec);
14191420
}
14201421

14211422
bool ec_can_decode(const shard_id_set &available_shards) const final {

src/osd/PGBackend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,8 @@ typedef std::shared_ptr<const OSDMap> OSDMapRef;
624624
ScrubMapBuilder &pos);
625625

626626
virtual uint64_t be_get_ondisk_size(uint64_t logical_size,
627-
shard_id_t shard_id) const = 0;
627+
shard_id_t shard_id,
628+
bool object_is_legacy_ec) const = 0;
628629

629630
virtual int be_deep_scrub(
630631
[[maybe_unused]] const Scrub::ScrubCounterSet& io_counters,

src/osd/ReplicatedBackend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,8 @@ class ReplicatedBackend : public PGBackend {
475475
ScrubMap::object &o) override;
476476

477477
uint64_t be_get_ondisk_size(uint64_t logical_size,
478-
shard_id_t unused) const final {
478+
shard_id_t unused,
479+
bool unused2) const final {
479480
return logical_size;
480481
}
481482
};

src/osd/scrubber/scrub_backend.cc

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,29 @@ ScrubBackend::ScrubBackend(ScrubBeListener& scrubber,
116116
}
117117

118118
uint64_t ScrubBackend::logical_to_ondisk_size(uint64_t logical_size,
119-
shard_id_t shard_id) const
119+
shard_id_t shard_id,
120+
bool hinfo_present,
121+
uint64_t expected_size) const
120122
{
121-
return m_pg.logical_to_ondisk_size(logical_size, shard_id);
123+
uint64_t ondisk_size = m_pg.logical_to_ondisk_size(logical_size, shard_id, false);
124+
125+
if (!hinfo_present || ondisk_size == expected_size) {
126+
return ondisk_size;
127+
}
128+
129+
// This object does not match the expected size, but hinfo is present. In this
130+
// case there are valid reasons for the shard to be *either* size when using
131+
// optimised EC. The following function checks the expected size from legacy
132+
// EC.
133+
uint64_t legacy_ondisk_size = m_pg.logical_to_ondisk_size(logical_size, shard_id, true);
134+
if (expected_size == legacy_ondisk_size) {
135+
return legacy_ondisk_size;
136+
}
137+
138+
// If this return is reached, then the size is corrupt and what we return
139+
// here is relevant to the error message only. Return the non-legacy value
140+
// as it might be more useful in debug.
141+
return ondisk_size;
122142
}
123143

124144
uint32_t ScrubBackend::generate_zero_buffer_crc(shard_id_t shard_id,
@@ -819,7 +839,9 @@ shard_as_auth_t ScrubBackend::possible_auth_shard(const hobject_t& obj,
819839
}
820840
}
821841

822-
uint64_t ondisk_size = logical_to_ondisk_size(oi.size, srd.shard);
842+
uint64_t ondisk_size = logical_to_ondisk_size(oi.size, srd.shard,
843+
smap_obj.attrs.contains(ECUtil::get_hinfo_key()),
844+
smap_obj.size);
823845
if (test_error_cond(smap_obj.size != ondisk_size, shard_info,
824846
&shard_info_wrapper::set_obj_size_info_mismatch)) {
825847

@@ -1500,7 +1522,9 @@ bool ScrubBackend::compare_obj_details(pg_shard_t auth_shard,
15001522
// ------------------------------------------------------------------------
15011523

15021524
// sizes:
1503-
uint64_t oi_size = logical_to_ondisk_size(auth_oi.size, shard.shard);
1525+
uint64_t oi_size = logical_to_ondisk_size(auth_oi.size, shard.shard,
1526+
candidate.attrs.contains(ECUtil::get_hinfo_key()),
1527+
candidate.size);
15041528
if (oi_size != candidate.size) {
15051529
fmt::format_to(std::back_inserter(out),
15061530
"{}size {} != size {} from auth oi {}",
@@ -1682,12 +1706,17 @@ void ScrubBackend::scrub_snapshot_metadata(ScrubMap& map, const pg_shard_t &srd)
16821706
}
16831707

16841708
if (oi) {
1685-
if (logical_to_ondisk_size(oi->size, srd.shard) != p->second.size) {
1709+
bool has_hinfo = p->second.attrs.contains(
1710+
ECLegacy::ECUtilL::get_hinfo_key());
1711+
if (logical_to_ondisk_size(oi->size, srd.shard, has_hinfo, p->second.size)
1712+
!= p->second.size) {
16861713
clog.error() << m_mode_desc << " " << m_pg_id << " " << soid
16871714
<< " : on disk size (" << p->second.size
16881715
<< ") does not match object info size (" << oi->size
16891716
<< ") adjusted for ondisk to ("
1690-
<< logical_to_ondisk_size(oi->size, srd.shard) << ")";
1717+
<< logical_to_ondisk_size(oi->size, srd.shard,
1718+
has_hinfo, p->second.size)
1719+
<< ")";
16911720
soid_error.set_size_mismatch();
16921721
this_chunk->m_error_counts.shallow_errors++;
16931722
}

src/osd/scrubber/scrub_backend.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,9 @@ class ScrubBackend {
556556

557557
// accessing the PG backend for this translation service
558558
uint64_t logical_to_ondisk_size(uint64_t logical_size,
559-
shard_id_t shard_id) const;
559+
shard_id_t shard_id,
560+
bool object_is_legacy_ec = false,
561+
uint64_t expected_size = 0) const;
560562
uint32_t generate_zero_buffer_crc(shard_id_t shard_id, int length) const;
561563
};
562564

src/osd/scrubber_common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ struct PgScrubBeListener {
266266

267267
// query the PG backend for the on-disk size of an object
268268
virtual uint64_t logical_to_ondisk_size(uint64_t logical_size,
269-
shard_id_t shard_id) const = 0;
269+
shard_id_t shard_id,
270+
bool object_is_legacy_ec) const = 0;
270271

271272
// used to verify our "cleanliness" before scrubbing
272273
virtual bool is_waiting_for_unreadable_object() const = 0;

src/test/osd/test_scrubber_be.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ class TestPg : public PgScrubBeListener {
9595
const pg_info_t& get_pg_info(ScrubberPasskey) const final { return m_info; }
9696

9797
uint64_t logical_to_ondisk_size(uint64_t logical_size,
98-
shard_id_t shard_id) const final
98+
shard_id_t shard_id,
99+
bool unused) const final
99100
{
100101
return logical_size;
101102
}

0 commit comments

Comments
 (0)