mirror of
https://github.com/ceph/ceph
synced 2025-01-10 21:20:46 +00:00
Merge pull request #50185 from ethanwu-syno/bluefs_tracker_56210
os/bluestore/bluefs: fix dir_link might add link that already exists in compact log Reviewed-by: Igor Fedotov <ifedotov@suse.com> Reviewed-by: Adam Kupczyk <akupczyk@redhat.com>
This commit is contained in:
commit
a182bc7eb4
@ -3929,7 +3929,7 @@ int BlueFS::open_for_write(
|
||||
std::string_view dirname,
|
||||
std::string_view filename,
|
||||
FileWriter **h,
|
||||
bool overwrite)/*_N_LD*/
|
||||
bool overwrite)/*_LND*/
|
||||
{
|
||||
_maybe_check_vselector_LNF();
|
||||
FileRef file;
|
||||
@ -3937,7 +3937,8 @@ int BlueFS::open_for_write(
|
||||
bool truncate = false;
|
||||
mempool::bluefs::vector<bluefs_extent_t> pending_release_extents;
|
||||
{
|
||||
std::unique_lock nl(nodes.lock);
|
||||
std::lock_guard ll(log.lock);
|
||||
std::lock_guard nl(nodes.lock);
|
||||
dout(10) << __func__ << " " << dirname << "/" << filename << dendl;
|
||||
map<string,DirRef>::iterator p = nodes.dir_map.find(dirname);
|
||||
DirRef dir;
|
||||
@ -3995,17 +3996,15 @@ int BlueFS::open_for_write(
|
||||
dout(20) << __func__ << " mapping " << dirname << "/" << filename
|
||||
<< " vsel_hint " << file->vselector_hint
|
||||
<< dendl;
|
||||
}
|
||||
{
|
||||
std::lock_guard ll(log.lock);
|
||||
log.t.op_file_update(file->fnode);
|
||||
if (create)
|
||||
log.t.op_dir_link(dirname, filename, file->fnode.ino);
|
||||
|
||||
std::lock_guard dl(dirty.lock);
|
||||
for (auto& p : pending_release_extents) {
|
||||
dirty.pending_release[p.bdev].insert(p.offset, p.length);
|
||||
}
|
||||
log.t.op_file_update(file->fnode);
|
||||
if (create)
|
||||
log.t.op_dir_link(dirname, filename, file->fnode.ino);
|
||||
|
||||
std::lock_guard dl(dirty.lock);
|
||||
for (auto& p : pending_release_extents) {
|
||||
dirty.pending_release[p.bdev].insert(p.offset, p.length);
|
||||
}
|
||||
}
|
||||
*h = _create_writer(file);
|
||||
|
||||
|
@ -1331,6 +1331,76 @@ TEST(BlueFS, test_4k_shared_alloc) {
|
||||
fs.umount();
|
||||
}
|
||||
|
||||
void create_files(BlueFS &fs,
|
||||
atomic_bool& stop_creating,
|
||||
atomic_bool& started_creating)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
stringstream ss;
|
||||
string dir = "dir.";
|
||||
ss << std::this_thread::get_id();
|
||||
dir.append(ss.str());
|
||||
dir.append(".");
|
||||
dir.append(to_string(i));
|
||||
ASSERT_EQ(0, fs.mkdir(dir));
|
||||
while (!stop_creating.load()) {
|
||||
string file = "file.";
|
||||
file.append(to_string(i));
|
||||
BlueFS::FileWriter *h;
|
||||
ASSERT_EQ(0, fs.open_for_write(dir, file, &h, false));
|
||||
ASSERT_NE(nullptr, h);
|
||||
fs.close_writer(h);
|
||||
i++;
|
||||
started_creating = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(BlueFS, test_concurrent_dir_link_and_compact_log_56210) {
|
||||
uint64_t size = 1048576 * 128;
|
||||
TempBdev bdev{size};
|
||||
ConfSaver conf(g_ceph_context->_conf);
|
||||
|
||||
conf.SetVal("bluefs_alloc_size", "65536");
|
||||
conf.SetVal("bluefs_compact_log_sync", "false");
|
||||
// make sure fsync always trigger log compact
|
||||
conf.SetVal("bluefs_log_compact_min_ratio", "0");
|
||||
conf.SetVal("bluefs_log_compact_min_size", "0");
|
||||
conf.ApplyChanges();
|
||||
|
||||
for (int i=0; i<10; ++i) {
|
||||
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 }));
|
||||
{
|
||||
atomic_bool stop_creating{false};
|
||||
atomic_bool started_creating{false};
|
||||
std::thread create_thread;
|
||||
create_thread = std::thread(create_files,
|
||||
std::ref(fs),
|
||||
std::ref(stop_creating),
|
||||
std::ref(started_creating));
|
||||
while (!started_creating.load()) {
|
||||
}
|
||||
BlueFS::FileWriter *h;
|
||||
ASSERT_EQ(0, fs.mkdir("foo"));
|
||||
ASSERT_EQ(0, fs.open_for_write("foo", "bar", &h, false));
|
||||
fs.fsync(h);
|
||||
fs.close_writer(h);
|
||||
|
||||
stop_creating = true;
|
||||
do_join(create_thread);
|
||||
|
||||
fs.umount(true); //do not compact on exit!
|
||||
ASSERT_EQ(0, fs.mount());
|
||||
fs.umount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
auto args = argv_to_vec(argc, argv);
|
||||
map<string,string> defaults = {
|
||||
|
Loading…
Reference in New Issue
Block a user