macOS Time Machine AFP monitoring: backup_time update on file modification
- Added afp_monitor.rs module to track AFP_AfpInfo backup_time - Open struct now has 'modified' flag to track file modifications - write.rs sets modified=true on successful write - close.rs calls AfpMonitor::update_backup_time() on modified files - create.rs calls AfpMonitor::init_afp_info() on new file creation - AFP_AfpInfo stored as xattr com.apple.aapl.AfpInfo - backup_time updated to current epoch time on modification Also includes: - LZ4 compression using lz4_flex crate - Case sensitivity conditional on backend capabilities - LDAP cfg feature gate fix - RAID rebuild reconstruction implementation - DOS attributes xattr persistence - Snapshot disk persistence Tests: 201 smb-server, 452 markbase-core (653 total)
This commit is contained in:
78
AGENTS.md
78
AGENTS.md
@@ -4433,3 +4433,81 @@ let response = namespace.build_referral_response("\\server\\dfs\\path");
|
||||
**结论**:Phase 7 (CTDB 集群) 复杂度高(⚠️⚠️⚠️⚠️⚠️),建议根据实际需求决定是否实施。
|
||||
|
||||
---
|
||||
|
||||
## macOS 兼容性 Phase 1-5 完成(2026-06-23)⭐⭐⭐⭐⭐
|
||||
|
||||
**Goal**: SMB server with full macOS compatibility (`mount_smbfs`, Time Machine, Finder).
|
||||
|
||||
### Progress
|
||||
- **macOS `rmdir` test fix** ✅ — `unlink_file_then_nonempty_dir_errors` passes on macOS. Root cause: macOS `unlink(dir)` returns `EACCES` not `EISDIR`. Fix: check `metadata().is_dir()` on `PermissionDenied`.
|
||||
- **Phase 1: AFP_AfpInfo 60 bytes** ✅ — `backend.rs` constant 32→60, `create.rs` uses `afp_info::AFP_INFO_SIZE`.
|
||||
- **Phase 2: Catia character conversion** ✅ — mapping values fixed to Samba `vfs_catia` standard (`U+F001`–`U+F009`), integrated via `SmbPath::from_utf16_mac()` and auto-detection in `create.rs`.
|
||||
- **Phase 3: AAPL RESOLVE_ID** ✅ — `AaplCreateContextRequest` extended with `resolve_file_id` field; `build_resolve_id_response()` in `aapl.rs`; handled in `create.rs` via `tree.opens` lookup.
|
||||
- **Phase 4: AAPL QUERY_DIR** ✅ — `SUPPORTS_OSX_COPYFILE` capability flag added.
|
||||
- **Phase 5: Time Machine persistence** ✅ — UUID persisted via xattr (`com.apple.TimeMachine.SupportedFilesStoreUUID`), reused across reconnects instead of regenerating on each `TreeConnect`.
|
||||
|
||||
### Key Decisions
|
||||
- AFP_AfpInfo 32→60 to match `afp_info.rs` spec — eliminates truncation of backup_time, prodos_info, reserved fields.
|
||||
- Catia mapping uses Samba `vfs_catia` standard private-range chars (`U+F001`–`U+F009`) — ensures compatibility with actual macOS SMB client behavior.
|
||||
- Path conversion auto-detects macOS private-range chars before calling `from_utf16_mac` — Windows clients unaffected.
|
||||
- AAPL RESOLVE_ID reads `FileId` from AAPL context (`resolve_file_id` field), creates `FileId::new(v, v)` to look up `tree.opens`.
|
||||
- SUPPORTS_OSX_COPYFILE advertised even without full copyfile offload — macOS falls back gracefully.
|
||||
- Time Machine UUID stored as xattr on share root — survives server restart.
|
||||
|
||||
### Test Results
|
||||
- **199/199** smb-server unit tests pass (was 193 + 1 pre-existing macOS failure, now fixed).
|
||||
- `test_build_resolve_id_response` comment/assertion fixed ("dir/file.txt" = 12 chars × 2 = 24 bytes, not 22).
|
||||
|
||||
### Relevant Files
|
||||
- `vendor/smb-server/src/fs/local.rs` — unlink macOS EACCES→is_dir fallback
|
||||
- `vendor/smb-server/src/backend.rs` — AFP_INFO_SIZE: 60
|
||||
- `vendor/smb-server/src/unicode_mapping.rs` — Catia mapping + helpers
|
||||
- `vendor/smb-server/src/path.rs` — from_utf16_mac
|
||||
- `vendor/smb-server/src/proto/messages/aapl.rs` — RESOLVE_ID response
|
||||
- `vendor/smb-server/src/handlers/create.rs` — Catia auto-detect, AAPL context processing, OSX_COPYFILE cap
|
||||
- `vendor/smb-server/src/handlers/tree_connect.rs` — TM UUID persistence
|
||||
- `docs/MACOS_COMPAT_DESIGN.md` — design document
|
||||
|
||||
---
|
||||
|
||||
## SMB Gap Analysis 完成 + LZ4 + Case Sensitivity(2026-06-23)⭐⭐⭐⭐⭐
|
||||
|
||||
**完成時間**:约 3 小时
|
||||
|
||||
### 实施内容 ⭐⭐⭐⭐⭐
|
||||
|
||||
| Gap | 状态 | 文件 | 说明 |
|
||||
|-----|------|------|------|
|
||||
| **TM share flags** | ✅ 完成 | `tree_connect.rs` | `RESTRICT_EXCLUSIVE_OPLOCKS` + `FORCE_LEVELII_OPLOCK` on TM shares |
|
||||
| **Catia in listings** | ✅ 完成 | `info_class.rs` | reverse mapping in `encode_dir_entry()` |
|
||||
| **Snapshot persistence** | ✅ 完成 | `snapshot.rs` | SnapshotManager save/load from disk |
|
||||
| **DOS attributes** | ✅ 完成 | `backend.rs`, `set_info.rs`, `local.rs` | `FileInfo.dos_attributes`, `Handle::set_attributes()`, `user.dos_attributes` xattr |
|
||||
| **S3/SmbVFS features** | ✅ 完成 | (verification) | Already return `Unsupported` via default traits |
|
||||
| **Case sensitivity** | ✅ 完成 | `create.rs:439-445` | AAPL `CASE_SENSITIVE` now conditional on `backend.capabilities().case_sensitive` |
|
||||
| **LZ4 compression** | ✅ 完成 | `compression.rs` | `lz4_flex` crate replaces Unsupported stub |
|
||||
| **LDAP cfg fix** | ✅ 完成 | `provider/mod.rs`, `cli/tools/smb_server.rs` | `#[cfg(feature = "ldap")]` gate added |
|
||||
|
||||
### Key Decisions ⭐⭐⭐⭐⭐
|
||||
- **Case sensitivity**: `BackendCapabilities.case_sensitive` was a dead field — never read anywhere, so AAPL always advertised `CASE_SENSITIVE` even on case-insensitive FS. Now wired via `tree_arc.read().await.share.backend.capabilities().case_sensitive`.
|
||||
- **LZ4**: uses `lz4_flex` (pure Rust, no C dependency). `compress_prepend_size` / `decompress_size_prepended`.
|
||||
- **DOS attributes**: stored in Linux `user.dos_attributes` xattr. Readable via `getfattr -n user.dos_attributes <file>`.
|
||||
- **Snapshot persistence**: manual file format (one snapshot per line), no serde dependency.
|
||||
- **LDAP module**: was `pub mod ldap` without feature gate — failed to compile without `ldap` feature.
|
||||
|
||||
### Test Results ⭐⭐⭐⭐⭐
|
||||
- **199/199** `smb-server` lib tests pass
|
||||
- **452/452** `markbase-core` lib tests pass (with `smb-server` feature)
|
||||
- **Total**: 651 tests pass
|
||||
|
||||
### Relevant Files
|
||||
- `vendor/smb-server/src/handlers/create.rs:439-445` — case sensitivity conditional
|
||||
- `vendor/smb-server/src/handlers/tree_connect.rs` — TM share flags
|
||||
- `vendor/smb-server/src/handlers/set_info.rs` — DOS attrs parsing
|
||||
- `vendor/smb-server/src/backend.rs` — `BackendCapabilities`, `FileInfo.dos_attributes`
|
||||
- `vendor/smb-server/src/fs/local.rs` — xattr DOS attrs
|
||||
- `vendor/smb-server/src/info_class.rs` — Catia reverse mapping
|
||||
- `vendor/smb-server/src/snapshot.rs` — disk persistence
|
||||
- `markbase-core/src/vfs/compression.rs` — LZ4 + ZSTD
|
||||
- `markbase-core/Cargo.toml` — `lz4_flex = "0.11"`
|
||||
- `markbase-core/src/provider/mod.rs` — `#[cfg(feature = "ldap")]`
|
||||
- `markbase-core/src/cli/tools/smb_server.rs` — LDAP compile fix
|
||||
|
||||
Reference in New Issue
Block a user