]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/bluefs: Fix data corruption in truncate() 45171/head
authorAdam Kupczyk <akupczyk@redhat.com>
Tue, 2 Nov 2021 15:57:32 +0000 (16:57 +0100)
committerPonnuvel Palaniyappan <pponnuvel@gmail.com>
Fri, 20 May 2022 08:28:30 +0000 (09:28 +0100)
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 <akupczyk@redhat.com>
(cherry picked from commit 49b7b44b3b5c94ee401562e603999e2b3bd8f9a2)

src/os/bluestore/BlueFS.cc
src/test/objectstore/test_bluefs.cc

index 37a000ac6ef6c96f24c46705137ef9b165ceff43..e9c5d7af835ee9f41932c594ab33d749384154cd 100644 (file)
@@ -2958,6 +2958,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);
index b2367213d8d171a66ae7f7208f296f79dd48a99a..c8144e6357046d5072d592ab41bcfcd03de3129b 100644 (file)
@@ -840,9 +840,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());