1
0
Fork 0
mirror of https://github.com/restic/restic.git synced 2025-03-16 00:00:05 +01:00

Keep track of open local files and close them. Still a lot of Access Denied errors related to removing files.

This commit is contained in:
klauspost 2015-08-12 17:32:03 +02:00
parent db26917bb5
commit 2e6187fe6f

View file

@ -8,6 +8,7 @@ import (
"os"
"path/filepath"
"sort"
"sync"
"github.com/restic/restic/backend"
)
@ -16,6 +17,8 @@ var ErrWrongData = errors.New("wrong data returned by backend, checksum does not
type Local struct {
p string
mu sync.Mutex
open map[string][]*os.File
}
// Open opens the local backend at dir.
@ -37,7 +40,7 @@ func Open(dir string) (*Local, error) {
}
}
return &Local{p: dir}, nil
return &Local{p: dir, open: make(map[string][]*os.File)}, nil
}
// Create creates all the necessary files and directories for a new local
@ -162,6 +165,11 @@ func (b *Local) Create() (backend.Blob, error) {
basedir: b.p,
}
b.mu.Lock()
open, _ := b.open["blobs"]
b.open["blobs"] = append(open, file)
b.mu.Unlock()
return &blob, nil
}
@ -198,7 +206,15 @@ func dirname(base string, t backend.Type, name string) string {
// Get returns a reader that yields the content stored under the given
// name. The reader should be closed after draining it.
func (b *Local) Get(t backend.Type, name string) (io.ReadCloser, error) {
return os.Open(filename(b.p, t, name))
file, err := os.Open(filename(b.p, t, name))
if err != nil {
return nil, err
}
b.mu.Lock()
open, _ := b.open[filename(b.p, t, name)]
b.open[filename(b.p, t, name)] = append(open, file)
b.mu.Unlock()
return file, nil
}
// GetReader returns an io.ReadCloser for the Blob with the given name of
@ -209,6 +225,11 @@ func (b *Local) GetReader(t backend.Type, name string, offset, length uint) (io.
return nil, err
}
b.mu.Lock()
open, _ := b.open[filename(b.p, t, name)]
b.open[filename(b.p, t, name)] = append(open, f)
b.mu.Unlock()
_, err = f.Seek(int64(offset), 0)
if err != nil {
return nil, err
@ -236,6 +257,15 @@ func (b *Local) Test(t backend.Type, name string) (bool, error) {
// Remove removes the blob with the given name and type.
func (b *Local) Remove(t backend.Type, name string) error {
// Close all open files we may have.
b.mu.Lock()
open, _ := b.open[filename(b.p, t, name)]
for _, file := range open {
file.Close()
}
b.open[filename(b.p, t, name)] = nil
b.mu.Unlock()
return os.Remove(filename(b.p, t, name))
}
@ -283,7 +313,20 @@ func (b *Local) List(t backend.Type, done <-chan struct{}) <-chan string {
}
// Delete removes the repository and all files.
func (b *Local) Delete() error { return os.RemoveAll(b.p) }
func (b *Local) Delete() error {
b.Close()
return os.RemoveAll(b.p)
}
// Close does nothing
func (b *Local) Close() error { return nil }
// Close closes all files
func (b *Local) Close() error {
b.mu.Lock()
for _, open := range b.open {
for _, file := range open {
file.Close()
}
}
b.open = make(map[string][]*os.File)
b.mu.Unlock()
return nil
}