Skip to content

Commit fd7b38b

Browse files
Merge pull request ceph#55008 from NitzanMordhai/wip-nitzan-clear-data-digest-for-crc-check
osd: full-object read CRC mismatch due to 'truncate' modifying oi.size w/o clearing 'data_digest'
2 parents b6f5f45 + 06e4c6f commit fd7b38b

File tree

7 files changed

+76
-6
lines changed

7 files changed

+76
-6
lines changed

src/osd/PrimaryLogPG.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6746,6 +6746,8 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
67466746
truncate_update_size_and_usage(ctx->delta_stats,
67476747
oi,
67486748
op.extent.truncate_size);
6749+
//truncate modify oi.size, need clear old data_digest and DIGEST flag
6750+
oi.clear_data_digest();
67496751
}
67506752
} else {
67516753
dout(10) << " truncate_seq " << op.extent.truncate_seq << " > current " << seq
@@ -6764,10 +6766,16 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops)
67646766

67656767
if (op.extent.length == 0) {
67666768
if (op.extent.offset > oi.size) {
6767-
t->truncate(
6768-
soid, op.extent.offset);
6769-
truncate_update_size_and_usage(ctx->delta_stats, oi,
6770-
op.extent.offset);
6769+
if (seq && (seq > op.extent.truncate_seq)) {
6770+
//do nothing
6771+
//write arrived after truncate, we should not truncate to offset
6772+
} else {
6773+
t->truncate(
6774+
soid, op.extent.offset);
6775+
truncate_update_size_and_usage(ctx->delta_stats, oi,
6776+
op.extent.offset);
6777+
oi.clear_data_digest();
6778+
}
67716779
} else {
67726780
t->nop(soid);
67736781
}

src/test/librados/io_cxx.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,18 @@ TEST_F(LibRadosIoPP, XattrListPP) {
495495
}
496496
}
497497

498+
TEST_F(LibRadosIoPP, CrcZeroWrite) {
499+
char buf[128];
500+
bufferlist bl;
501+
502+
ASSERT_EQ(0, ioctx.write("foo", bl, 0, 0));
503+
ASSERT_EQ(0, ioctx.write("foo", bl, 0, sizeof(buf)));
504+
505+
ObjectReadOperation read;
506+
read.read(0, bl.length(), NULL, NULL);
507+
ASSERT_EQ(0, ioctx.operate("foo", &read, &bl));
508+
}
509+
498510
TEST_F(LibRadosIoECPP, SimpleWritePP) {
499511
SKIP_IF_CRIMSON();
500512
char buf[128];
@@ -865,6 +877,22 @@ TEST_F(LibRadosIoECPP, RmXattrPP) {
865877
ASSERT_EQ(-ENOENT, ioctx.rmxattr("foo_rmxattr", attr2));
866878
}
867879

880+
TEST_F(LibRadosIoECPP, CrcZeroWrite) {
881+
SKIP_IF_CRIMSON();
882+
set_allow_ec_overwrites(pool_name, true);
883+
char buf[128];
884+
memset(buf, 0xcc, sizeof(buf));
885+
bufferlist bl;
886+
887+
ASSERT_EQ(0, ioctx.write("foo", bl, 0, 0));
888+
ASSERT_EQ(0, ioctx.write("foo", bl, 0, sizeof(buf)));
889+
890+
ObjectReadOperation read;
891+
read.read(0, bl.length(), NULL, NULL);
892+
ASSERT_EQ(0, ioctx.operate("foo", &read, &bl));
893+
recreate_pool();
894+
}
895+
868896
TEST_F(LibRadosIoECPP, XattrListPP) {
869897
SKIP_IF_CRIMSON();
870898
char buf[128];

src/test/librados/test_cxx.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,21 @@ std::string create_one_ec_pool_pp(const std::string &pool_name, Rados &cluster)
121121
return "";
122122
}
123123

124+
std::string set_allow_ec_overwrites_pp(const std::string &pool_name, Rados &cluster, bool allow)
125+
{
126+
std::ostringstream oss;
127+
bufferlist inbl;
128+
int ret = cluster.mon_command(
129+
"{\"prefix\": \"osd pool set\", \"pool\": \"" + pool_name + "\", \"var\": \"allow_ec_overwrites\", \"val\": \"" + (allow ? "true" : "false") + "\"}",
130+
inbl, NULL, NULL);
131+
if (ret) {
132+
cluster.shutdown();
133+
oss << "mon_command osd pool set pool:" << pool_name << " pool_type:erasure allow_ec_overwrites true failed with error " << ret;
134+
return oss.str();
135+
}
136+
return "";
137+
}
138+
124139
std::string connect_cluster_pp(librados::Rados &cluster)
125140
{
126141
return connect_cluster_pp(cluster, {});

src/test/librados/test_cxx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ std::string create_one_pool_pp(const std::string &pool_name,
1212
const std::map<std::string, std::string> &config);
1313
std::string create_one_ec_pool_pp(const std::string &pool_name,
1414
librados::Rados &cluster);
15+
std::string set_allow_ec_overwrites_pp(const std::string &pool_name,
16+
librados::Rados &cluster, bool allow);
1517
std::string connect_cluster_pp(librados::Rados &cluster);
1618
std::string connect_cluster_pp(librados::Rados &cluster,
1719
const std::map<std::string, std::string> &config);

src/test/librados/testcase_cxx.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ Rados RadosTestPP::s_cluster;
193193
void RadosTestPP::SetUpTestCase()
194194
{
195195
init_rand();
196-
197196
auto pool_prefix = fmt::format("{}_", ::testing::UnitTest::GetInstance()->current_test_case()->name());
198197
pool_name = get_temp_pool_name(pool_prefix);
199198
ASSERT_EQ("", create_one_pool_pp(pool_name, s_cluster));
@@ -405,3 +404,15 @@ void RadosTestECPP::TearDown()
405404
ioctx.close();
406405
}
407406

407+
void RadosTestECPP::recreate_pool()
408+
{
409+
SKIP_IF_CRIMSON();
410+
ASSERT_EQ(0, destroy_one_ec_pool_pp(pool_name, s_cluster));
411+
ASSERT_EQ("", create_one_ec_pool_pp(pool_name, s_cluster));
412+
SetUp();
413+
}
414+
415+
void RadosTestECPP::set_allow_ec_overwrites(std::string pool, bool allow)
416+
{
417+
ASSERT_EQ("", set_allow_ec_overwrites_pp(pool, cluster, allow));
418+
}

src/test/librados/testcase_cxx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ class RadosTestECPP : public RadosTestPP {
117117
protected:
118118
static void SetUpTestCase();
119119
static void TearDownTestCase();
120+
void recreate_pool();
121+
void set_allow_ec_overwrites(std::string pool, bool allow=true);
120122
static librados::Rados s_cluster;
121123
static std::string pool_name;
122124

src/test/pybind/test_rados.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,12 @@ def test_cmpext(self):
312312
def test_list_objects_empty(self):
313313
eq(list(self.ioctx.list_objects()), [])
314314

315-
def test_list_objects(self):
315+
def test_read_crc(self):
316316
self.ioctx.write('a', b'')
317+
self.ioctx.write('a', b'', 5)
318+
self.ioctx.read('a')
319+
320+
def test_list_objects(self):
317321
self.ioctx.write('b', b'foo')
318322
self.ioctx.write_full('c', b'bar')
319323
self.ioctx.append('d', b'jazz')

0 commit comments

Comments
 (0)