A Rust port of cshatag - a tool to detect silent data corruption.
cshatag stores the SHA-256 hash and modification time of each file as extended attributes (user.shatag.sha256 and user.shatag.ts). When run again, it compares the stored values against the current file state to detect corruption.
The key detection is silent data corruption: when a file's mtime is unchanged but its content hash has changed, indicating the file was modified without touching the timestamp (e.g., bit rot on disk).
| Status | Meaning |
|---|---|
<new> |
File has never been tagged (both xattrs missing) |
<ok> |
File is unchanged (hash and mtime match) |
<timechange> |
mtime changed but hash is the same (e.g., touch) |
<outdated> |
Both mtime and hash changed (normal edit) |
<corrupt> |
Silent data corruption - mtime unchanged but hash differs |
git clone <repo-url>
cd cshatag-rs
cargo build --releaseThe binary will be at target/release/cshatag.
cshatag [OPTIONS] <FILE>...
| Flag | Description |
|---|---|
-q |
Quiet: don't print <ok> files |
-qq |
Very quiet: only print <corrupt> files and errors (implies -q) |
-r, --recursive |
Recursively descend into directories (skips symlinks) |
--remove |
Remove previously stored extended attributes |
--dry-run |
Read-only mode: no changes written |
--fix |
Force-update the stored hash on corrupt files |
-h, --help |
Print help |
-V, --version |
Print version |
Check all files recursively, suppress <ok> output:
cshatag -q -r /path/to/filesCheck all files, only show errors and corrupt files:
cshatag -qq -r /path/to/filesRemove cshatag's extended attributes from all files:
cshatag -r --remove /path/to/filesDry run (no changes):
cshatag --dry-run -r /path/to/files| Code | Meaning |
|---|---|
| 0 | Success |
| 2 | One or more files could not be opened |
| 3 | One or more files is not a regular file |
| 4 | Extended attributes could not be written |
| 5 | At least one corrupt file detected |
| 6 | Multiple error types occurred |
cshatag uses two extended attributes on each file:
user.shatag.sha256- SHA-256 hash as 64-character hex stringuser.shatag.ts- Modification time asSSSSSSSSSS.NNNNNNNNN(seconds.nanoseconds)
The filesystem must be mounted with user_xattr enabled.
cshatag-rs is format-compatible with the original cshatag and shatag. Files tagged by one tool can be read by the other.
- Linux: 100ns resolution (matches SMB protocol limits)
- macOS: 1s resolution (matches macOS SMB client limits)
MIT