Skip to content

Conversation

@weisd
Copy link
Contributor

@weisd weisd commented Nov 17, 2025

Fix: FileMeta Version Handling and Delete Operations

Summary

This PR fixes critical issues in file metadata version handling, specifically addressing:

  1. Version sorting logic inconsistencies
  2. Delete version operations with nil UUID handling
  3. Directory object version ID assignment
  4. Version ID validation and serialization improvements

Type of Change

  • New Feature
  • Bug Fix
  • Documentation
  • Performance Improvement
  • Test/CI
  • Refactor
  • Other:

Related Issues

#844

Problem

The previous implementation had several version-related issues:

  • Version sorting used a simple reverse() which didn't properly handle all version attributes
  • Delete version operations failed when handling nil UUIDs (used for directory objects)
  • Directory objects incorrectly used Uuid::max() instead of Uuid::nil() as default version ID
  • Version ID validation was too strict, rejecting valid nil UUIDs for directory objects
  • Version ID serialization filtered out nil UUIDs, causing inconsistencies

Changes

1. Fixed Version Sorting Logic (filemeta.rs)

  • Replaced simple reverse() with comprehensive multi-field sorting
  • Changed sort order to descending by mod_time, version_type, version_id, and flags
  • Ensures consistent version ordering across all operations
  • Applied to both sort_versions() and sort_versions_by_modtime() methods

2. Fixed Delete Version with Nil UUID (filemeta.rs)

  • Added nil UUID handling in delete_version() method
  • Fixed version matching logic to properly handle nil UUIDs
  • Removed redundant version search loop, consolidating logic into single iteration
  • Ensures delete operations work correctly for directory objects

3. Fixed Version ID Serialization (filemeta.rs)

  • Removed nil UUID filtering in FileMetaVersionHeader::unmarshal()
  • Changed to always store version_id as Some(Uuid), even for nil UUIDs
  • Fixed into_fileinfo() to preserve nil UUIDs instead of filtering them out
  • Maintains consistency between serialized and in-memory representations

4. Fixed Add Version with Nil UUID (filemeta.rs)

  • Added nil UUID assignment in add_version() when version_id is None
  • Ensures all versions have a valid UUID for internal operations

5. Fixed Directory Object Version ID (ecfs.rs, options.rs)

  • Changed default version ID for directory objects from Uuid::max() to Uuid::nil()
  • Applied to del_opts(), get_opts(), and put_opts() functions
  • Consistent with nil UUID usage for directory objects

6. Fixed Version ID Validation (options.rs)

  • Updated validation to allow nil UUID for directory objects
  • Removed unnecessary versioned bucket check for version ID validation
  • Allows nil UUID to pass validation when appropriate

7. Fixed Version Sorting in SetDisks (set_disk.rs)

  • Removed unnecessary reverse() after sorting versions
  • Sorting now produces correct order without reversal

8. Code Quality Improvements

  • Changed Vec<FileInfo> to &[FileInfo] in delete_versions_internal() for better performance
  • Updated to modern Rust string formatting ({err} instead of {}, err)
  • Removed unnecessary comments and dead code
  • Fixed clippy warnings

Checklist

  • I have read and followed the CONTRIBUTING.md guidelines
  • Passed make pre-commit
  • Added/updated necessary tests
  • Documentation updated (if needed)
  • CI/CD passed (if applicable)

Impact

  • Breaking change (compatibility)
    the version number generated for empty directory objects has been changed from uuid::max to uuid::nil. If there are previously created empty directories, they must be manually deleted from the data directory

here is a shell command to help delete existing empty directories:

#!/usr/bin/env bash
set -euo pipefail

DATA_DIR=${1:-}
if [[ -z "$DATA_DIR" || ! -d "$DATA_DIR" ]]; then
  echo "Usage: $0 <data_directory>"
  exit 1
fi

find "$DATA_DIR" -type d -name '*__XLDIR__' -prune -print -exec rm -rf {} +
  • Requires doc/config/deployment update
  • Other impact:

Additional Notes


Thank you for your contribution! Please ensure your PR follows the community standards (CODE_OF_CONDUCT.md) and sign the CLA if this is your first contribution.

@weisd weisd changed the title Fix/filemetaversion fix: filemeta version handling and delete operations Nov 17, 2025
@weisd weisd merged commit 85bc0ce into main Nov 18, 2025
14 checks passed
@weisd weisd deleted the fix/filemetaversion branch November 18, 2025 01:24
houseme added a commit that referenced this pull request Nov 18, 2025
…:rustfs/rustfs into copilot/implement-adaptive-buffer-sizing

* 'copilot/implement-adaptive-buffer-sizing' of github.com:rustfs/rustfs:
  fix: filemeta version handling and delete operations (#879)
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.

1 participant