1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
7 #include <gtest/gtest.h>
8 #include "global/global_init.h"
9 #include "global/global_context.h"
10 #include "common/ceph_context.h"
11 #include "common/ceph_argparse.h"
12 #include "include/stringify.h"
13 #include "common/errno.h"
15 #include "blk/BlockDevice.h"
19 TempBdev(uint64_t size
)
20 : path
{get_temp_bdev(size
)}
25 const std::string path
;
27 static string
get_temp_bdev(uint64_t size
)
30 string fn
= "ceph_test_bluefs.tmp.block." + stringify(getpid())
31 + "." + stringify(++n
);
32 int fd
= ::open(fn
.c_str(), O_CREAT
|O_RDWR
|O_TRUNC
, 0644);
34 int r
= ::ftruncate(fd
, size
);
39 static void rm_temp_bdev(string f
)
45 TEST(KernelDevice
, Ticket45337
) {
46 // Large (>=2 GB) writes are incomplete when bluefs_buffered_io = true
48 uint64_t size
= 1048576ull * 8192;
49 TempBdev bdev
{ size
};
51 const bool buffered
= true;
53 std::unique_ptr
<BlockDevice
> b(
54 BlockDevice::create(g_ceph_context
, bdev
.path
, NULL
, NULL
,
55 [](void* handle
, void* aio
) {}, NULL
));
57 // writing a bit less than 4GB
58 for (auto i
= 0; i
< 4000; i
++) {
59 string
s(1048576, 'a' + (i
% 28));
62 uint64_t magic_offs
= bl
.length();
68 int r
= b
->open(bdev
.path
);
70 std::cerr
<< "open " << bdev
.path
<< " failed" << std::endl
;
74 std::unique_ptr
<IOContext
> ioc(new IOContext(g_ceph_context
, NULL
));
76 auto r
= b
->aio_write(0, bl
, ioc
.get(), buffered
);
79 if (ioc
->has_pending_aios()) {
80 b
->aio_submit(ioc
.get());
85 r
= b
->read_random(magic_offs
, sizeof(outbuf
), outbuf
, buffered
);
87 ASSERT_EQ(memcmp(s
.c_str(), outbuf
, sizeof(outbuf
)), 0);
92 int main(int argc
, char **argv
) {
93 vector
<const char*> args
;
94 argv_to_vec(argc
, (const char **)argv
, args
);
96 map
<string
,string
> defaults
= {
97 { "debug_bdev", "1/20" }
100 auto cct
= global_init(&defaults
, args
, CEPH_ENTITY_TYPE_CLIENT
,
101 CODE_ENVIRONMENT_UTILITY
,
102 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
);
103 common_init_finish(g_ceph_context
);
104 g_ceph_context
->_conf
.set_val(
105 "enable_experimental_unrecoverable_data_corrupting_features",
107 g_ceph_context
->_conf
.apply_changes(nullptr);
109 ::testing::InitGoogleTest(&argc
, argv
);
110 return RUN_ALL_TESTS();