diff --git a/pkg/fs/file.go b/pkg/fs/file.go index bf7909a..b6ef1bb 100644 --- a/pkg/fs/file.go +++ b/pkg/fs/file.go @@ -4,6 +4,7 @@ package fs import ( "cachefs/pkg/provider" + "cachefs/pkg/provider/crypto" "context" "errors" "io" @@ -95,13 +96,13 @@ func (f *File) Read(p []byte) (n int, err error) { return } if err != nil { - if !IsIOErr(err) { + if !IsIOErr(err) && err != crypto.ErrDecrypt { log.Error(err, "error reading cache file") return } n, err = f.readSource(p) if err != nil { - log.Error(err, "error reading source file") + log.Error(err, "error reading fallback source file") return } } diff --git a/pkg/fs/metadata.go b/pkg/fs/metadata.go index bdc2ae0..30103aa 100644 --- a/pkg/fs/metadata.go +++ b/pkg/fs/metadata.go @@ -475,9 +475,6 @@ func (md *Metadata) writer() { } func (md *Metadata) WriteAt(data []byte, pos int64) (int, error) { - if md.ctx.Err() == context.Canceled { - return 0, context.Canceled - } err := md.err.Load() if err != nil && err.err != nil { return 0, err.err @@ -488,6 +485,9 @@ func (md *Metadata) WriteAt(data []byte, pos int64) (int, error) { return 0, err } } + if md.ctx.Err() == context.Canceled { + return 0, context.Canceled + } wa := writeAt{pos: pos} ret := streamingPool.Get() n := len(data) @@ -507,6 +507,16 @@ func (md *Metadata) WriteAt(data []byte, pos int64) (int, error) { return n, nil } +func (md *Metadata) Stat() (os.FileInfo, error) { + if md.f == nil { + err := md.openCacheFile() + if err != nil { + return nil, err + } + } + return md.f.Stat() +} + func (md *Metadata) openCacheFile() error { md.mu.Lock() defer md.mu.Unlock() @@ -525,13 +535,3 @@ func (md *Metadata) openCacheFile() error { md.writer() return nil } - -func (md *Metadata) Stat() (os.FileInfo, error) { - if md.f == nil { - err := md.openCacheFile() - if err != nil { - return nil, err - } - } - return md.f.Stat() -} diff --git a/pkg/provider/crypto/file.go b/pkg/provider/crypto/file.go index 9cb1bff..2090018 100644 --- a/pkg/provider/crypto/file.go +++ b/pkg/provider/crypto/file.go @@ -163,7 +163,7 @@ func (f *file) ReadAt(p []byte, pos int64) (n int, err error) { defer f.rmu.Unlock() cn, _, roff := align(pos) var last bool - if f.r.cn != cn { + if f.r.cn != cn || roff >= int64(len(f.r.unread)) { _, err = f.Seek(pos, io.SeekStart) if err != nil { return diff --git a/pkg/provider/crypto/reader.go b/pkg/provider/crypto/reader.go index 9134b11..3977f39 100644 --- a/pkg/provider/crypto/reader.go +++ b/pkg/provider/crypto/reader.go @@ -77,6 +77,8 @@ func (r *reader) Read(p []byte) (int, error) { return n, nil } +var ErrDecrypt = errors.New("failed to decrypt and authenticate payload chunk") + func (r *reader) readChunk() (last bool, err error) { if len(r.unread) != 0 { panic("stream: internal error: readChunk called with dirty buffer") @@ -105,7 +107,7 @@ func (r *reader) readChunk() (last bool, err error) { out, err = r.a.Open(r.outBuf, r.nonce[:], in, nil) } if err != nil { - return false, errors.New("failed to decrypt and authenticate payload chunk") + return false, ErrDecrypt } incNonce(&r.nonce)