Skip to content

Conversation

generall
Copy link
Member

  • check filesystem on start and do some simple mmap test to make sure it is persisted

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@generall generall requested a review from timvisee June 16, 2025 10:54
Copy link
Member

@timvisee timvisee 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 I have two review remarks:

I've also added some more file systems. Including APFS which is the default on modern macs, which is known to be sound.

Comment on lines +220 to +251
// Check if the filesystem is compatible with Qdrant
match check_fs_info(&settings.storage.storage_path) {
memory::checkfs::FsCheckResult::Good => {} // Do nothing
memory::checkfs::FsCheckResult::Unknown(details) => {
match check_mmap_functionality(&settings.storage.storage_path) {
Ok(true) => {
log::warn!(
"There is a potential issue with the filesystem for storage path {}. Details: {details}",
settings.storage.storage_path
);
}
Ok(false) => {
log::error!(
"Filesystem check failed for storage path {}. Details: {details}",
settings.storage.storage_path
);
}
Err(e) => {
log::error!(
"Unable to check mmap functionality for storage path {}. Details: {details}, error: {e}",
settings.storage.storage_path
);
}
}
}
memory::checkfs::FsCheckResult::Bad(details) => {
log::error!(
"Filesystem check failed for storage path {}. Details: {details}",
settings.storage.storage_path
);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I vote to make the warnings/errors a bit more pronounced, with a clearer description and call to action for the user. We should expect that the user is not in context at all.

Suggested change
// Check if the filesystem is compatible with Qdrant
match check_fs_info(&settings.storage.storage_path) {
memory::checkfs::FsCheckResult::Good => {} // Do nothing
memory::checkfs::FsCheckResult::Unknown(details) => {
match check_mmap_functionality(&settings.storage.storage_path) {
Ok(true) => {
log::warn!(
"There is a potential issue with the filesystem for storage path {}. Details: {details}",
settings.storage.storage_path
);
}
Ok(false) => {
log::error!(
"Filesystem check failed for storage path {}. Details: {details}",
settings.storage.storage_path
);
}
Err(e) => {
log::error!(
"Unable to check mmap functionality for storage path {}. Details: {details}, error: {e}",
settings.storage.storage_path
);
}
}
}
memory::checkfs::FsCheckResult::Bad(details) => {
log::error!(
"Filesystem check failed for storage path {}. Details: {details}",
settings.storage.storage_path
);
}
}
// Check if the filesystem is compatible with Qdrant
match check_fs_info(&settings.storage.storage_path) {
memory::checkfs::FsCheckResult::Good => {} // Do nothing
memory::checkfs::FsCheckResult::Unknown(details) => {
match check_mmap_functionality(&settings.storage.storage_path) {
Ok(true) => {
log::warn!("Unknown filesystem, may expect data loss and corruption! See documentation for compatible setups.");
log::warn!("- Docs: https://qdrant.tech/documentation/guides/installation/#storage");
log::warn!("- Path: {}", settings.storage.storage_path);
log::warn!("- Details: {details}");
}
Ok(false) => {
log::error!("Detected filesystem problems, expect data loss and corruption! See docs for compatible setups.");
log::error!("- Docs: https://qdrant.tech/documentation/guides/installation/#storage");
log::error!("- Path: {}", settings.storage.storage_path);
log::error!("- Details: {details}");
}
Err(e) => {
log::error!(
"Failed to check filesystem mmap compatibility at {}. Details: {details}, error: {e}",
settings.storage.storage_path,
);
}
}
}
memory::checkfs::FsCheckResult::Bad(details) => {
log::error!("Unsupported filesystem, expect data loss and corruption! See documentation for compatible setups.");
log::error!("- Docs: https://qdrant.tech/documentation/guides/installation/#storage");
log::error!("- Path: {}", settings.storage.storage_path);
log::error!("- Details: {details}");
}
}

For example:

Version: 1.14.2-dev, build: 38be2617
Access web UI at http://localhost:6333/dashboard

2025-06-16T12:47:35.045373Z ERROR qdrant: Detected filesystem problems, expect data loss and corruption! See docs for compatible setups.
2025-06-16T12:47:35.045403Z ERROR qdrant: - Docs: https://qdrant.tech/documentation/guides/installation/#storage
2025-06-16T12:47:35.045410Z ERROR qdrant: - Path: ./storage
2025-06-16T12:47:35.045416Z ERROR qdrant: - Details: Container filesystem detected - storage might be lost with container re-creation

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought we prefer single error line, which might be easier to grep in tools like graphana

Co-authored-by: Tim Visée <tim+github@visee.me>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
lib/common/memory/src/checkfs.rs (1)

169-172: Create the directory before calling statfs to prevent false-negatives

Returning Unknown("Path does not exist") puts perfectly valid first-run deployments into the “unknown / non-POSIX” bucket and triggers the costly mmap probe (plus a scary log line).
Creating the directory (or propagating the error if creation fails) avoids that extra I/O, aligns with the earlier review suggestion, and removes noise from the logs.

 pub fn check_fs_info(path: impl AsRef<Path>) -> FsCheckResult {
-    if !path.as_ref().exists() {
-        return FsCheckResult::Unknown("Path does not exist".to_string());
-    }
+    if let Err(e) = create_dir_all(path.as_ref()) {
+        return FsCheckResult::Bad(format!("Cannot create storage directory: {e}"));
+    }
🧹 Nitpick comments (3)
lib/common/memory/src/checkfs.rs (3)

87-87: Typo: hfs+, not htf+

The string "htf+" will never match a real filesystem name; it should be "hfs+".

-            "hfs" | "htf+" => Self::Hfs,
+            "hfs" | "hfs+" => Self::Hfs,

203-210: Drop the premature read-only mmap to save one mapping + syscall

mmap_seq is created before the file is populated and is never used; it is immediately dropped.
Opening it afterwards (or omitting it entirely) removes an unnecessary open + mmap round-trip.

-    let mmap_seq = open_read_mmap(
-        &magic_file_path,
-        AdviceSetting::Advice(Advice::Sequential),
-        false,
-    )?;
+    // Delay read-only check until after the write/flush cycle

(If the sequential‐advice read is important later, open it right before the final comparison.)


55-72: Minor clarity: use explicit pattern alternatives instead of bitwise-OR comments

The magic-number match arms already leverage Rust’s | pattern alternation.
Consider splitting multi-value arms onto separate lines for readability and to avoid confusing the | with a bitwise OR for newcomers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 486bb36 and cfe2ade.

📒 Files selected for processing (1)
  • lib/common/memory/src/checkfs.rs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
lib/common/memory/src/checkfs.rs (1)
lib/common/memory/src/mmap_ops.rs (3)
  • create_and_ensure_length (12-42)
  • open_read_mmap (44-62)
  • open_write_mmap (64-78)
⏰ Context from checks skipped due to timeout of 90000ms (14)
  • GitHub Check: test-shard-snapshot-api-s3-minio
  • GitHub Check: test-snapshot-operations-s3-minio
  • GitHub Check: storage-compat-test
  • GitHub Check: test-low-resources
  • GitHub Check: Basic TLS/HTTPS tests
  • GitHub Check: test-consistency
  • GitHub Check: test-consensus-compose
  • GitHub Check: integration-tests
  • GitHub Check: rust-tests (ubuntu-latest)
  • GitHub Check: integration-tests-consensus
  • GitHub Check: rust-tests-no-rocksdb (ubuntu-latest)
  • GitHub Check: rust-tests (macos-latest)
  • GitHub Check: lint
  • GitHub Check: rust-tests (windows-latest)

@generall generall merged commit 8792f51 into dev Jun 16, 2025
18 checks passed
@generall generall deleted the check-filesystem-on-start branch June 16, 2025 16:13
generall added a commit that referenced this pull request Jul 17, 2025
* check filesystem on start and do some simple mmap test to make sure it is persisted

* fmt

* fix fs type read on non-linux

* feature-flag for fs-check supported platforms + fs check with sub-folder

* fmt

* try larger magic file

* minor fixes

* fix compile on windows

* Add FAT, exFAT and APFS file systems

* Update lib/common/memory/src/checkfs.rs

Co-authored-by: Tim Visée <tim+github@visee.me>

---------

Co-authored-by: timvisee <tim@visee.me>
Co-authored-by: Tim Visée <tim+github@visee.me>
@coderabbitai coderabbitai bot mentioned this pull request Jul 18, 2025
6 tasks
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.

2 participants