backend/local: fix "operation not supported" when unlocking

If the repo is on a mounted folder that doesn't support chmod (like
SMB), it was causing an "operation not supported" error when trying to
chmod 666 a file before deleting it.

But it isn't generally needed before deleting a file (the folder
permissions matter there, not the file permissions). So, just drop it.
This commit is contained in:
Michael Terry 2025-11-15 20:59:14 -05:00
parent 71432c7f4b
commit 7f3e3b77ce
4 changed files with 26 additions and 7 deletions

View file

@ -0,0 +1,8 @@
Bugfix: Fix "chmod not supported" errors when unlocking
Restic 0.18.0 introduced a bug that caused "chmod xxx: operation not supported"
errors to appear when unlocking with a stale lock, on a local file repository
that did not support chmod (like CIFS or WebDAV mounted via FUSE). Restic now
just doesn't bother calling chmod in that case on Unix, as it is unnecessary.
https://github.com/restic/restic/issues/5595

View file

@ -255,13 +255,7 @@ func (b *Local) Stat(_ context.Context, h backend.Handle) (backend.FileInfo, err
func (b *Local) Remove(_ context.Context, h backend.Handle) error {
fn := b.Filename(h)
// reset read-only flag
err := os.Chmod(fn, 0666)
if err != nil && !os.IsPermission(err) {
return errors.WithStack(err)
}
return os.Remove(fn)
return removeFile(fn)
}
// List runs fn for each file in the backend which has the type t. When an

View file

@ -52,3 +52,7 @@ func setFileReadonly(f string, mode os.FileMode) error {
return err
}
func removeFile(f string) error {
return os.Remove(f)
}

View file

@ -2,6 +2,8 @@ package local
import (
"os"
"github.com/restic/restic/internal/errors"
)
// Can't explicitly flush directory changes on Windows.
@ -16,3 +18,14 @@ func isMacENOTTY(_ error) bool { return false }
func setFileReadonly(_ string, _ os.FileMode) error {
return nil
}
func removeFile(f string) error {
// Reset read-only flag,
// as Windows won't let you delete a read-only file
err := os.Chmod(f, 0666)
if err != nil && !os.IsPermission(err) {
return errors.WithStack(err)
}
return os.Remove(f)
}