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:
Warren
2026-06-24 00:46:33 +08:00
parent 5300b672cb
commit 57fd6a475f
33 changed files with 1211 additions and 253 deletions

View File

@@ -0,0 +1,75 @@
# macOS SMB Compatibility Design
## Overview
Enable seamless macOS SMB client connectivity through five phases of
implementation inspired by Samba's `vfs_fruit` and `vfs_catia` modules.
## Gap Analysis Summary
| Feature | Samba vfs_fruit | MarkBase SMB | Status |
|---------|----------------|--------------|--------|
| AFP_AfpInfo (60-byte) | Native xattr | **Truncated to 32 bytes** | ⚠️ P0 bug |
| Catia char mapping | vfs_catia | Functions exist, **not integrated** | ❌ P1 |
| AAPL RESOLVE_ID | AAPL context | **Advertised, not implemented** | ❌ P1 |
| AAPL QUERY_DIR | READ_DIR_ATTR | **Advertised, not implemented** | ❌ P2 |
| Time Machine xattr | vfs_fruit | Set on TreeConnect, **not persisted** | ❌ P2 |
| Finder tags | _kMDItemUserTags | Not implemented | ❌ Future |
| OSX copyfile offload | FSCTL_SRV_COPYCHUNK | Not implemented | ❌ Future |
## Phase 1 — AFP_AfpInfo 60-Byte Fix (P0)
**Problem**: `backend.rs` defines `AFP_INFO_SIZE = 32`, truncating the 60-byte
`AfpInfo` structure to only the `FinderInfo` portion. Backup time, ProDos info,
and reserved fields are silently discarded.
**Fix**: Change the constant to 60 to match `afp_info.rs`.
**Files**: `vendor/smb-server/src/backend.rs`
## Phase 2 — Catia Character Conversion (P1)
**Problem**: macOS clients send NTFS-illegal characters (`:*?"<>|`) encoded as
Unicode private-range code points (`U+F001``U+F070`). These are rejected by
`SmbPath::from_utf16()` which validates against NTFS-illegal characters.
The conversion functions already exist in `unicode_mapping.rs` but are never
called before path validation.
**Fix**: Convert private-range chars to ASCII equivalents **before** calling
`SmbPath::from_utf16()` in `create.rs` and `query_directory.rs`.
**Files**:
- `vendor/smb-server/src/handlers/create.rs`
- `vendor/smb-server/src/path.rs` (add public conversion helper)
## Phase 3 — AAPL RESOLVE_ID (P1)
**Problem**: macOS clients send AAPL create context with command = RESOLVE_ID
to map a FileId back to a path. The server advertises `SUPPORT_RESOLVE_ID` but
does not handle the command — it silently returns `None`.
**Fix**: Handle `SMB2_CRTCTX_AAPL_RESOLVE_ID` in the AAPL context processing.
Return the path associated with the requested FileId.
**Files**: `vendor/smb-server/src/handlers/create.rs`
## Phase 4 — AAPL QUERY_DIR (P2)
**Problem**: macOS uses AAPL SERVER_QUERY to request directory attributes in
the CREATE response. The server handles SERVER_QUERY but does not provide
`READ_DIR_ATTR` enhancements.
**Fix**: When AAPL SERVER_QUERY includes `READ_DIR_ATTR`, return directory
metadata (file count, free space) in the response.
**Files**: `vendor/smb-server/src/handlers/create.rs`
## Phase 5 — Time Machine Persistence (P2)
**Problem**: `com.apple.TimeMachine.*` xattrs are set on every TreeConnect
with a new random UUID. The UUID changes on reconnect, confusing macOS.
**Fix**: Check for existing xattrs before setting new ones. Persist the UUID.
**Files**: `vendor/smb-server/src/handlers/tree_connect.rs`