From 49b7b44b3b5c94ee401562e603999e2b3bd8f9a2 Mon Sep 17 00:00:00 2001 From: Adam Kupczyk Date: Tue, 2 Nov 2021 16:57:32 +0100 Subject: [PATCH] os/bluestore/bluefs: Fix data corruption in truncate() It is possible to create condition in which a BlueFS contains file that is corrupted. It can happen when BlueFS replay log is on device A and we just wrote to device B and truncated file. Scenario: 1) write to file h1 on SLOW device 2) flush h1 (initiate transfer, but no fdatasync yet) 3) truncate h1 4) write to file h2 on DB 5) fsync h2 (forces replay log to be written, after fdatasync to DB) 6) poweroff Fixes: https://tracker.ceph.com/issues/53129 Signed-off-by: Adam Kupczyk --- src/os/bluestore/BlueFS.cc | 1 + src/test/objectstore/test_bluefs.cc | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/os/bluestore/BlueFS.cc b/src/os/bluestore/BlueFS.cc index f34996be3e0..f125bc15bf0 100644 --- a/src/os/bluestore/BlueFS.cc +++ b/src/os/bluestore/BlueFS.cc @@ -2923,6 +2923,7 @@ int BlueFS::_truncate(FileWriter *h, uint64_t offset) ceph_abort_msg("truncate up not supported"); } ceph_assert(h->file->fnode.size >= offset); + _flush_bdev_safely(h); vselector->sub_usage(h->file->vselector_hint, h->file->fnode.size); h->file->fnode.size = offset; vselector->add_usage(h->file->vselector_hint, h->file->fnode.size); diff --git a/src/test/objectstore/test_bluefs.cc b/src/test/objectstore/test_bluefs.cc index 799996da17f..58bd1ad16e4 100644 --- a/src/test/objectstore/test_bluefs.cc +++ b/src/test/objectstore/test_bluefs.cc @@ -842,9 +842,9 @@ TEST(BlueFS, test_truncate_stable_53129) { TempBdev bdev_slow{size_slow}; BlueFS fs(g_ceph_context); - ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_WAL, "wal", false, 0)); - ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, "db", false, 0)); - ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_SLOW, "slow", false, 0)); + ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_WAL, bdev_wal.path, false, 0)); + ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, bdev_db.path, false, 0)); + ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_SLOW, bdev_slow.path, false, 0)); uuid_d fsid; ASSERT_EQ(0, fs.mkfs(fsid, { BlueFS::BDEV_DB, true, true })); ASSERT_EQ(0, fs.mount()); -- 2.39.5