Skip to content

Conversation

@kfirtoledo
Copy link
Collaborator

This PR introduces the file management module used by the filesystem offloading connector.

Included in this PR:

  • Adds file_io.cpp and file_io.hpp
  • Implements low level file operations for the fs connector
  • Supports atomic writes, file existence checks, and read operations

@kfirtoledo kfirtoledo requested a review from orozery November 23, 2025 09:57
@kfirtoledo kfirtoledo changed the title [feat]: Add file management module (file_io) for fs connector [fs_connector][feat]: Add file management module (file_io) for fs connector Nov 23, 2025
Copy link
Collaborator

@dannyharnik dannyharnik left a comment

Choose a reason for hiding this comment

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

Looks good but need to ensure we don't hit the race condition I pointed out

…nector

Signed-off-by: Kfir Toledo <kfir.toledo@ibm.com>
Copy link
Collaborator

@orozery orozery left a comment

Choose a reason for hiding this comment

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

Good job!


// Write to a temporary file to ensure atomic replace on rename
// Include thread_stream_idx so each thread uses a unique temporary file
std::string tmp_path = target_path + std::to_string(thread_stream_idx) + ".tmp.";
Copy link
Collaborator

Choose a reason for hiding this comment

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

What if you have multiple vllm instances writing to the same path?
I think it's thus safer to generate a temporary file name instead of target_path + std::to_string(thread_stream_idx) + ".tmp.".

Copy link
Collaborator

Choose a reason for hiding this comment

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

The stream_idx was added to avoid such a case (assuming it is unique).
Could use a random string as well...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I will change it to random to be on the safe side.

ifs.seekg(0, std::ios::beg);

// Acquire pinned buffer of the required size
auto [pinned_ptr, pinned_size] = get_thread_local_pinned(file_size);
Copy link
Collaborator

Choose a reason for hiding this comment

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

where is get_thread_local_pinned defined?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

}

// Read file into pinned memory
ifs.read(reinterpret_cast<char*>(pinned_ptr), file_size);
Copy link
Collaborator

Choose a reason for hiding this comment

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

What about setting a (1MB?) read buffer like you did on the other function?
e.g.

ifs.rdbuf()->pubsetbuf(...);

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For ifstream, the data is read in one large call directly into the pinned staging buffer, so there is no need for an extra buffer.
For ofstream, the internal buffer is small and leads to many write syscalls, so we use a 1MB thread-local buffer to speed up writes.
In the next version, I plan to check more deeply whether fstream gives the best read and write performance.

Signed-off-by: Kfir Toledo <kfir.toledo@ibm.com>
@kfirtoledo
Copy link
Collaborator Author

@orozery and @dannyharnik PTAL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants