Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Filestore] issue-2189: support O_DIRECT in local filestore #2188

Open
wants to merge 3 commits into
base: users/evgenybud/local-filestore-o-direct-base
Choose a base branch
from

Conversation

budevg
Copy link
Collaborator

@budevg budevg commented Oct 1, 2024

@budevg budevg added large-tests Launch large tests for PR filestore Add this label to run only cloud/filestore build and tests on PR asan Launch builds with address sanitizer along with regular build tsan Launch builds with thread sanitizer along with regular build labels Oct 1, 2024
@budevg budevg changed the base branch from users/evgenybud/local-filestore-o-direct-base to main October 1, 2024 10:10
@budevg budevg added asan Launch builds with address sanitizer along with regular build and removed asan Launch builds with address sanitizer along with regular build labels Oct 1, 2024
@budevg budevg force-pushed the users/evgenybud/local-filestore-o-direct branch from eb6f31f to 2082bdd Compare October 1, 2024 10:30
@budevg budevg changed the title NBSNEBIUS-472: support O_DIRECT in local filestore ssue-2189: support O_DIRECT in local filestore Oct 1, 2024
@budevg budevg changed the base branch from main to users/evgenybud/local-filestore-o-direct-base October 1, 2024 10:34
@budevg budevg changed the title ssue-2189: support O_DIRECT in local filestore issue-2189: support O_DIRECT in local filestore Oct 1, 2024
@budevg budevg changed the title issue-2189: support O_DIRECT in local filestore [Filestore] issue-2189: support O_DIRECT in local filestore Oct 1, 2024
cloud/filestore/libs/service_local/fs_data.cpp Outdated Show resolved Hide resolved
cloud/filestore/libs/service_local/fs_data.cpp Outdated Show resolved Hide resolved
cloud/filestore/libs/service_local/service_ut.cpp Outdated Show resolved Hide resolved
cloud/filestore/libs/vfs_fuse/fs_impl_data.cpp Outdated Show resolved Hide resolved
@@ -192,12 +197,13 @@ void TFileSystem::Read(
const auto& response = future.GetValue();
if (auto self = ptr.lock(); CheckResponse(self, *callContext, req, response)) {
const auto& buffer = response.GetBuffer();
auto alignOffset = response.GetAlignOffset();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а почему в ответе не отдать выровненный буфер?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Изначально проблема была в том, что у нас буфер передаётся в protobuf, а там bytes это TString, у которого нельзя контролировать выравнивание. Поэтому все эти хитрости. Сейчас я сделал, что буфер, как обычно, возвращается, а потом в нём можно найти правильное выравнивание.

cloud/filestore/public/api/protos/data.proto Outdated Show resolved Hide resolved
cloud/storage/core/libs/common/aligned_string.h Outdated Show resolved Hide resolved
Copy link
Contributor

github-actions bot commented Oct 1, 2024

Note

This is an automated comment that will be appended during run.

🔴 linux-x86_64-relwithdebinfo: some tests FAILED for commit 2082bdd.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
1880 1736 0 144 0 0

Copy link
Contributor

github-actions bot commented Oct 1, 2024

Note

This is an automated comment that will be appended during run.

🔴 linux-x86_64-relwithdebinfo: some tests FAILED for commit 2082bdd.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
1880 1736 0 144 0 0

🔴 linux-x86_64-release-asan: some tests FAILED for commit 2082bdd.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
1866 1724 0 142 0 0

Copy link
Contributor

github-actions bot commented Oct 1, 2024

Note

This is an automated comment that will be appended during run.

🔴 linux-x86_64-relwithdebinfo: some tests FAILED for commit 2082bdd.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
1880 1736 0 144 0 0

🔴 linux-x86_64-release-asan: some tests FAILED for commit 2082bdd.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
1866 1724 0 142 0 0

🔴 linux-x86_64-release-tsan: some tests FAILED for commit 2082bdd.

TESTS PASSED ERRORS FAILED SKIPPED MUTED?
1256 1240 0 16 0 0

@budevg budevg force-pushed the users/evgenybud/local-filestore-o-direct branch from fedda35 to 2082bdd Compare October 3, 2024 06:24
@budevg budevg requested a review from qkrorlqr October 3, 2024 06:51

TArrayRef<char> data(b.begin(), b.vend());
TArrayRef<char> data((char*)b->Begin(), (char*)b->End());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

давай лучше без c-style cast
давай сделаем static_cast тут или вообще сделаем в TAlignedBuffer методы, возвращающие char*

@@ -29,6 +29,9 @@ namespace {
\
xxx(AsyncDestroyHandleEnabled, bool, false )\
xxx(AsyncHandleOperationPeriod, TDuration, TDuration::MilliSeconds(50) )\
\
xxx(DirectIoEnabled, bool, false )\
xxx(DirectIoAlign, ui32, 4096 )\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

давай лучше использовать size_literals.h для такого
то есть в данном случае это 4_KB

@@ -0,0 +1 @@
#include "aligned_buffer.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

давай все-таки в cpp имплементацию двинем? мы в хедерах стараемся держать все-таки в основном имплементацию темплейтов, т.к. ее в общем случае в cpp не передвинешь, но тут же не темплейт

const char* AlignedData;

public:
static std::pair<const char*, size_t> ExtractAlignedData(const TString& buffer, ui32 align)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ой, у нас же есть структура со смыслом "указатель + размер" - это TStringBuf, давай вернем его

if (alignedData > buffer.end()) {
ythrow TServiceError(E_ARGUMENT)
<< "Extracting unaligned buffer " << (void*)buffer.begin()
<< " with size " << buffer.size();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

еще align надо в текст ошибки добавить

, AlignedData(Buffer.begin())
{
if (align) {
Y_ASSERT(IsPowerOf2(align)); // align should be power of 2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Y_DEBUG_ABORT_UNLESS обычно делаем

ythrow TServiceError(E_ARGUMENT)
<< "Initializing from unaligned buffer "
<< (void*)Buffer.begin()
<< " with size " << Buffer.size();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align еще надо


const char* End() const
{
if (!Buffer) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

этот if выглядит ненужным


const char* Begin() const
{
if (!Buffer) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

этот if выглядит ненужным - ты же для пустого буфера все равно инициализируешь AlignedData значением Buffer.begin()

Buffer.resize(AlignedDataOffset() + size);
}

TString& GetBuffer()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я non-const геттеры стараюсь называть AccessXXX, а не GetXXX, чтоб в месте вызова было сразу видно, что ты планируешь изменять то, что получил

давай назовем этот метод AccessBuffer()
а то я в месте вызова немного задумался, увидев геттер

ythrow TServiceError(E_ARGUMENT)
<< "Extracting unaligned buffer " << (void*)buffer.begin()
<< " with size " << buffer.size();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

наверное, стоит также проверить, что длина aligned-куска >= тому, что запросили при чтении

т.к. если в реализации storage-слоя есть баг (или мисконфиг - флаг про поддержку o direct забыли), который приводит к тому, что мы отдаем буфер без выравнивания, получится, что мы отрежем голову буфера, хотя в ней есть нужные нам данные, и после этого останемся с буфером меньшего размера, чем хотели прочитать

@@ -191,13 +193,16 @@ void TFileSystem::Read(
.Subscribe([=, ptr = weak_from_this()] (const auto& future) {
const auto& response = future.GetValue();
if (auto self = ptr.lock(); CheckResponse(self, *callContext, req, response)) {
const auto& buffer = response.GetBuffer();
auto align = Config->GetDirectIoEnabled() ? Config->GetDirectIoAlign() : 0;
auto [alignedData, size] = TAlignedBuffer::ExtractAlignedData(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

нам бы как-то вместе с ответом доставить информацию о том, у нас есть в буфере выравнивание или нет

иначе получается хрупко - легко допустить ошибку, из-за которой сторадж-слой будет отдавать буферы без пустого места в голове, нужного для выравнивания, а этот код будет считать, что такое пустое место там есть, и будет отрезать у буфера невыровненную голову, хотя на самом деле в ней лежат данные

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно прямо в ответе отдавать инфу про alignment - в смысле, не тут по месту вычислять align, а брать из ответа

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
asan Launch builds with address sanitizer along with regular build filestore Add this label to run only cloud/filestore build and tests on PR large-tests Launch large tests for PR tsan Launch builds with thread sanitizer along with regular build
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants