From a293fd9aef6cf86a9598878d7a99afe74e807f5f Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 27 Feb 2021 00:02:13 +0100 Subject: [PATCH] local: Ignore files in intermediate folders For example the data folder of a repository might contain hidden files which caused list operations to fail. --- changelog/unreleased/issue-3302 | 8 ++++++++ internal/backend/local/local.go | 13 ++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 changelog/unreleased/issue-3302 diff --git a/changelog/unreleased/issue-3302 b/changelog/unreleased/issue-3302 new file mode 100644 index 000000000..f86e38a39 --- /dev/null +++ b/changelog/unreleased/issue-3302 @@ -0,0 +1,8 @@ +Bugfix: Fix `fdopendir: not a directory` error for local backend + +The `check`, `list packs`, `prune` and `rebuild-index` commands failed +for the local backend when the `data` folder in the repository contained +files. This has been fixed. + +https://github.com/restic/restic/issues/3302 +https://github.com/restic/restic/pull/3308 diff --git a/internal/backend/local/local.go b/internal/backend/local/local.go index 8e9625734..11d450d9d 100644 --- a/internal/backend/local/local.go +++ b/internal/backend/local/local.go @@ -245,7 +245,7 @@ func (b *Local) List(ctx context.Context, t restic.FileType, fn func(restic.File if subdirs { err = visitDirs(ctx, basedir, fn) } else { - err = visitFiles(ctx, basedir, fn) + err = visitFiles(ctx, basedir, fn, false) } if b.IsNotExist(err) { @@ -279,7 +279,7 @@ func visitDirs(ctx context.Context, dir string, fn func(restic.FileInfo) error) } for _, f := range sub { - err = visitFiles(ctx, filepath.Join(dir, f), fn) + err = visitFiles(ctx, filepath.Join(dir, f), fn, true) if err != nil { return err } @@ -287,12 +287,19 @@ func visitDirs(ctx context.Context, dir string, fn func(restic.FileInfo) error) return ctx.Err() } -func visitFiles(ctx context.Context, dir string, fn func(restic.FileInfo) error) error { +func visitFiles(ctx context.Context, dir string, fn func(restic.FileInfo) error, ignoreNotADirectory bool) error { d, err := fs.Open(dir) if err != nil { return err } + if ignoreNotADirectory { + fi, err := d.Stat() + if err != nil || !fi.IsDir() { + return err + } + } + sub, err := d.Readdir(-1) if err != nil { // ignore subsequent errors