From 6e0cde076a609c69a8d8e43b3a7bcbafbcd56811 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 3 Jul 2026 12:14:21 +0100 Subject: [PATCH] vfs/vfscache: fix IO error by recreating the cache file if it has been removed _createFile opened the cache file with O_RDWR but not O_CREATE, relying on the file already existing. When the file had been removed underneath rclone - either by _checkObject dropping a stale entry during open, or by external deletion - the open failed and surfaced a hard "IO error" to the application instead of recreating the file. Add O_CREATE so the cache self-heals in that case. --- vfs/vfscache/item.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/vfs/vfscache/item.go b/vfs/vfscache/item.go index d82e90da7..b65cba924 100644 --- a/vfs/vfscache/item.go +++ b/vfs/vfscache/item.go @@ -471,7 +471,10 @@ func (item *Item) _createFile(osPath string) (err error) { } item.modified = false // t0 := time.Now() - fd, err := file.OpenFile(osPath, os.O_RDWR, 0600) + // Use O_CREATE so the cache file is recreated if it has been removed + // underneath us (e.g. _checkObject dropped a stale entry, or an external + // deletion), rather than failing the open with a hard IO error. + fd, err := file.OpenFile(osPath, os.O_RDWR|os.O_CREATE, 0600) // fs.Debugf(item.name, "OpenFile took %v", time.Since(t0)) if err != nil { return fmt.Errorf("vfs cache item: open failed: %w", err) @@ -560,6 +563,10 @@ func (item *Item) open(o fs.Object) (err error) { return nil } fs.Debugf(item.name, "vfs cache: cache file vanished during grace period, recreating") + // The backing file is gone, so any ranges are invalid. + item.info.Rs = nil + // It also can't be dirty if the data no longer exists. + item.info.Dirty = false if item.fd != nil { _ = item.fd.Close() item.fd = nil