Skip to content

[Filestore] issue-5432: add basic async open support (vfs_fuse)#6588

Open
budevg wants to merge 1 commit into
mainfrom
users/evgenybud/async-open-pr1
Open

[Filestore] issue-5432: add basic async open support (vfs_fuse)#6588
budevg wants to merge 1 commit into
mainfrom
users/evgenybud/async-open-pr1

Conversation

@budevg

@budevg budevg commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

@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 msan Launch builds with memory sanitizer along with regular build ubsan Launch builds with undefined behaviour sanitizer along with regular build labels Jul 23, 2026
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Note

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

Note

All workloads for linux-x86_64-relwithdebinfo have completed.

Tip

Planned checks for linux-x86_64-relwithdebinfo.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Note

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

Note

All workloads for linux-x86_64-release-ubsan have completed.

Tip

Planned checks for linux-x86_64-release-ubsan.

  • 🔴 all (build failed, log)

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Note

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

Note

All workloads for linux-x86_64-release-tsan have completed.

Tip

Planned checks for linux-x86_64-release-tsan.

  • 🔴 all (build failed, log)

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Note

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

Note

All workloads for linux-x86_64-release-asan have completed.

Tip

Planned checks for linux-x86_64-release-asan.

  • 🔴 all (build failed, log)

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Note

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

Note

All workloads for linux-x86_64-release-msan have completed.

Tip

Planned checks for linux-x86_64-release-msan.

  • 🔴 all (build failed, log)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8ceaf58309

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

};
}

rpc ConfirmCreateHandle(TConfirmCreateHandleRequest) returns (TConfirmCreateHandleResponse) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add storage handling for the new confirmation RPC

This exposes ConfirmCreateHandle over gRPC, but the storage/Kikimr plumbing is not wired for the new method: cloud/filestore/libs/storage/api/service.h does not add a TEvService event id or include it in FILESTORE_SERVICE_REQUESTS, and the tablet/service actors dispatch only those request lists. In deployments using the real storage service rather than the null/local test handlers, async opens will call Session->ConfirmCreateHandle but there is no storage route/handler for the confirmation, so the queued handle confirmations cannot reach the tablet.

Useful? React with 👍 / 👎.

optional double FakeTxPageFaultsProbability = 527;

// Async processing of read-only create handle requests.
optional bool AsyncCreateHandleEnabled = 528;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Publish AsyncCreateHandleEnabled in session features

Adding this storage config knob is not enough to enable the vhost path: vfs_fuse/loop.cpp reads only TFileStoreFeatures::AsyncCreateHandleEnabled from CreateSession, but storage/core/config.*, tablet_actor_createsession.cpp, and service_local/fs_session.cpp do not expose an accessor or call features->SetAsyncCreateHandleEnabled(...). When this option is set in storage/local config, sessions still advertise false, so Open() never sets AllowAsyncCreateHandle outside tests that inject features directly.

Useful? React with 👍 / 👎.

xxx(ReadData, __VA_ARGS__) \
xxx(WriteData, __VA_ARGS__) \
xxx(AllocateData, __VA_ARGS__) \
xxx(ConfirmCreateHandle, __VA_ARGS__) \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve existing EFileStoreRequest values

Placing ConfirmCreateHandle here inserts it before Fsync/FsyncDir, endpoint requests, and the DescribeData/AddData blob requests, changing their numeric EFileStoreRequest values. Profile log records store only static_cast<ui32>(requestType), and the analytics/replay code casts that number back to EFileStoreRequest, so logs captured before this change for those later request types will be decoded or replayed as the wrong operation; append the new value after the existing range or assign stable explicit values instead.

Useful? React with 👍 / 👎.


// If set, the handle was returned before durable persistence completed and
// the client must confirm it.
bool HandleCreatedAsync = 7;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Set HandleCreatedAsync in the real create path

The VFS queues a confirmation only when response.GetHandleCreatedAsync() is true, but this commit never wires any production CreateHandle path to set the new bit (repo search finds SetHandleCreatedAsync only in fs_ut.cpp). In the real tablet path an async read-only create can complete before durability via TabletUnsafeAsyncReadOnlyCreateHandleEnabled, yet the response still has this field false, so even with the client feature enabled the open is treated as persisted and no durable confirmation entry is written.

Useful? React with 👍 / 👎.


// If set, the client allows CreateHandle to return before the handle is
// durably persisted.
bool AllowAsyncCreateHandle = 14;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor AllowAsyncCreateHandle before async completion

This new request bit is the only signal that the client can persist and later confirm an uncommitted handle, but the real tablet async branch still checks only TabletUnsafeAsyncReadOnlyCreateHandleEnabled and read-only flags (tablet_actor_createhandle.cpp:532) and does not read request.GetAllowAsyncCreateHandle() anywhere outside tests. With that storage option enabled, clients that did not set the bit, including vhost sessions where the async-create feature/queue is disabled, can still get a pre-durable handle and will never enqueue a confirmation.

Useful? React with 👍 / 👎.

message TQueueEntry
{
oneof Request {
TCreateHandleRequest CreateHandleRequest = 1;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we can override this because we don't store TCreateHandleRequests anywhere yet

with_lock (HandleOpsQueueLock) {
HandleOpsQueue->PopFront();
}
RetryDelayedRelease();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

RetryDelayedRelease looks out of place in CompleteAsyncCreateHandle

});
} else if (entry.HasQueuedCreateHandleRequest()) {
const auto& requestInfo = entry.GetQueuedCreateHandleRequest();
auto request = CreateConfirmRequest(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

CreateConfirmCreateHandleRequest

ScheduleProcessHandleOpsQueue();
}

void TFileSystem::RetryDelayedRelease()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ProcessDelayedRelease?

Comment on lines +394 to +395
RetryDelayedRelease();
ScheduleProcessHandleOpsQueue();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It looks like these two calls are always used together

Maybe we should incorporate ScheduleProcessHandleOpsQueue into RetryDelayedRelease?

IMPLEMENT_DEFAULT_METHOD(AccessNode, NProto)
IMPLEMENT_DEFAULT_METHOD(ReadLink, NProto)
IMPLEMENT_DEFAULT_METHOD(RemoveNodeXAttr, NProto)
IMPLEMENT_DEFAULT_METHOD(ConfirmCreateHandle, NProto)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks like it can break existing profile logs

Comment on lines +450 to +454
// A release can be appended to DelayedReleaseQueue after a queue
// completion has already checked it. Retry here as well to avoid
// leaving that release stranded until another entry completes.
g.Release();
RetryDelayedRelease();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we are fixing existing behavior, it would be better to do it in a separate PR

Comment on lines +143 to +146
STORAGE_ERROR(
"ConfirmCreateHandle request failed: "
<< "filesystem " << self->Config->GetFileSystemId()
<< " error: " << FormatError(error));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It looks like such errors should never occur, so let's report a critical event

return;
}

ReportHandleOpsQueueProcessError(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think this should be attributed to the handle ops queue. It looks like a separate critical event


auto callContext = MakeIntrusive<TCallContext>(
Config->GetFileSystemId(),
CreateRequestId());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should we use requestInfo.GetRequestId() here as well?

TEST_REQUEST_TYPE(57, WriteBlob);
TEST_REQUEST_TYPE(58, ConfirmAddData);
TEST_REQUEST_TYPE(59, CancelAddData);
TEST_REQUEST_TYPE(46, ConfirmCreateHandle);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

seems that now all old logs will become incompatible with new logs (because of the change of event types of many requests which are already present in old logs) - doesn't look good

SessionState,
this);

FileSystem->Init();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why was this moved from Init()?

<< "filesystem " << self->Config->GetFileSystemId()
<< " error: " << FormatError(error));

if (GetErrorKind(error) == EErrorKind::ErrorRetriable) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

retriable errors are supposed to be handled at another layer - in DurableClient

<< " error: " << FormatError(destroyError));

if (GetErrorKind(destroyError) ==
EErrorKind::ErrorRetriable)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same comment about retriable errors

@SvartMetal
SvartMetal requested a review from WilyTiger July 24, 2026 10:39
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 msan Launch builds with memory sanitizer along with regular build tsan Launch builds with thread sanitizer along with regular build ubsan Launch builds with undefined behaviour sanitizer along with regular build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants