]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: bluefs unittest for truncate bug
authorAdam Kupczyk <akupczyk@ibm.com>
Fri, 10 Jan 2025 10:07:18 +0000 (10:07 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Fri, 17 Jan 2025 08:41:24 +0000 (08:41 +0000)
Unittest showing 2 different flavours of problems:
1) bluefs log corruption
2) bluefs sigsegv

Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
(cherry picked from commit f2b5e2fa0a9274c1667fccafa597fff9be7a74b1)
+ fixes for add_block_device
+ fix for bad usage of std::string's fill constructor

src/test/objectstore/test_bluefs.cc

index 9c9921d02e3248c2afdfb90fccd5657dd5d4cfb0..2677e6898dfa69d226efc4b36f41f550234ffef2 100644 (file)
@@ -1479,6 +1479,91 @@ TEST(BlueFS, truncate_drops_allocations) {
   }
 }
 
+TEST(BlueFS, test_69481_truncate_corrupts_log) {
+  uint64_t size = 1048576 * 128;
+  TempBdev bdev{size};
+  BlueFS fs(g_ceph_context);
+  ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, bdev.path, false, 1048576));
+  uuid_d fsid;
+  ASSERT_EQ(0, fs.mkfs(fsid, { BlueFS::BDEV_DB, false, false }));
+  ASSERT_EQ(0, fs.mount());
+  ASSERT_EQ(0, fs.maybe_verify_layout({ BlueFS::BDEV_DB, false, false }));
+
+  BlueFS::FileWriter *f = nullptr;
+  BlueFS::FileWriter *a = nullptr;
+  ASSERT_EQ(0, fs.mkdir("dir"));
+  ASSERT_EQ(0, fs.open_for_write("dir", "test-file", &f, false));
+  ASSERT_EQ(0, fs.open_for_write("dir", "just-allocate", &a, false));
+
+  // create 4 distinct extents in file f
+  // a is here only to prevent f from merging extents together
+  fs.preallocate(f->file, 0, 0x10000);
+  fs.preallocate(a->file, 0, 0x10000);
+  fs.preallocate(f->file, 0, 0x20000);
+  fs.preallocate(a->file, 0, 0x20000);
+  fs.preallocate(f->file, 0, 0x30000);
+  fs.preallocate(a->file, 0, 0x30000);
+  fs.preallocate(f->file, 0, 0x40000);
+  fs.preallocate(a->file, 0, 0x40000);
+  fs.close_writer(a);
+
+  fs.truncate(f, 0);
+  fs.fsync(f);
+
+  bufferlist bl;
+  bl.append(std::string(0x15678, ' '));
+  f->append(bl);
+  fs.truncate(f, 0x15678);
+  fs.fsync(f);
+  fs.close_writer(f);
+
+  fs.umount();
+  // remount to verify
+  ASSERT_EQ(0, fs.mount());
+  fs.umount();
+}
+
+TEST(BlueFS, test_69481_truncate_asserts) {
+  uint64_t size = 1048576 * 128;
+  TempBdev bdev{size};
+  BlueFS fs(g_ceph_context);
+  ASSERT_EQ(0, fs.add_block_device(BlueFS::BDEV_DB, bdev.path, false, 1048576));
+  uuid_d fsid;
+  ASSERT_EQ(0, fs.mkfs(fsid, { BlueFS::BDEV_DB, false, false }));
+  ASSERT_EQ(0, fs.mount());
+  ASSERT_EQ(0, fs.maybe_verify_layout({ BlueFS::BDEV_DB, false, false }));
+
+  BlueFS::FileWriter *f = nullptr;
+  BlueFS::FileWriter *a = nullptr;
+  ASSERT_EQ(0, fs.mkdir("dir"));
+  ASSERT_EQ(0, fs.open_for_write("dir", "test-file", &f, false));
+  ASSERT_EQ(0, fs.open_for_write("dir", "just-allocate", &a, false));
+
+  // create 4 distinct extents in file f
+  // a is here only to prevent f from merging extents together
+  fs.preallocate(f->file, 0, 0x10000);
+  fs.preallocate(a->file, 0, 0x10000);
+  fs.preallocate(f->file, 0, 0x20000);
+  fs.preallocate(a->file, 0, 0x20000);
+  fs.preallocate(f->file, 0, 0x30000);
+  fs.preallocate(a->file, 0, 0x30000);
+  fs.preallocate(f->file, 0, 0x40000);
+  fs.preallocate(a->file, 0, 0x40000);
+  fs.close_writer(a);
+
+  fs.truncate(f, 0);
+  fs.fsync(f);
+
+  bufferlist bl;
+  bl.append(std::string(0x35678, ' '));
+  f->append(bl);
+  fs.truncate(f, 0x35678);
+  fs.fsync(f);
+  fs.close_writer(f);
+
+  fs.umount();
+}
+
 int main(int argc, char **argv) {
   auto args = argv_to_vec(argc, argv);
   map<string,string> defaults = {