Skip to content

Instantly share code, notes, and snippets.

@thomasjm
Created July 15, 2026 22:57
Show Gist options
  • Select an option

  • Save thomasjm/a76fabd691911437874e155d12bd1cdd to your computer and use it in GitHub Desktop.

Select an option

Save thomasjm/a76fabd691911437874e155d12bd1cdd to your computer and use it in GitHub Desktop.
Reproduce truncated read after rclone rc vfs/forget (kernel FUSE attr cache not invalidated)
#!/usr/bin/env bash
# Reproduce a truncated read after vfs/forget on an rclone mount.
# Usage: ./repro.sh [rclone-binary] [attr-timeout] e.g. ./repro.sh rclone 60s
set -euo pipefail
rclone="${1:-rclone}"
attr_timeout="${2:-60s}"
# Setup: a temp dir served over WebDAV, then mounted with rclone.
remote=$(mktemp -d); mnt=$(mktemp -d)
printf 'old' > "$remote/file" # the file starts at 3 bytes
"$rclone" serve webdav "$remote" --addr localhost:8080 --dir-cache-time 0 &>/dev/null &
serve=$!; sleep 1
"$rclone" mount ":webdav,url='http://localhost:8080':" "$mnt" \
--attr-timeout "$attr_timeout" --dir-cache-time 1000h \
--rc --rc-addr localhost:5572 --rc-no-auth &>/dev/null &
mount=$!
until mountpoint -q "$mnt"; do sleep 0.1; done
trap 'fusermount3 -u "$mnt" &>/dev/null; kill $mount $serve 2>/dev/null; rm -rf "$remote" "$mnt"' EXIT
new='a much longer replacement string' # 32 bytes
cat "$mnt/file" >/dev/null # step 2: read once -> kernel caches size 3
printf '%s' "$new" > "$remote/file" # step 3: grow the file on the remote
"$rclone" rc --rc-addr localhost:5572 --rc-no-auth vfs/forget file=file >/dev/null # step 4: forget
result=$(cat "$mnt/file") # step 5: read again
echo "read back: '$result' (${#result} bytes, file is ${#new})"
[ "${#result}" -eq "${#new}" ] && echo "OK" || echo "TRUNCATED"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment