vfs: cache the size of the object in the read handle

This commit is contained in:
Nick Craig-Wood 2017-11-20 17:57:13 +00:00
parent f0ed384786
commit 76b151984c

View file

@ -17,6 +17,7 @@ type ReadFileHandle struct {
r *fs.Account r *fs.Account
o fs.Object o fs.Object
readCalled bool // set if read has been called readCalled bool // set if read has been called
size int64 // size of the object
offset int64 // offset of read of o offset int64 // offset of read of o
roffset int64 // offset of Read() calls roffset int64 // offset of Read() calls
noSeek bool noSeek bool
@ -48,6 +49,7 @@ func newReadFileHandle(f *File, o fs.Object) (*ReadFileHandle, error) {
noSeek: f.d.vfs.Opt.NoSeek, noSeek: f.d.vfs.Opt.NoSeek,
file: f, file: f,
hash: hash, hash: hash,
size: o.Size(),
} }
return fh, nil return fh, nil
} }
@ -135,7 +137,7 @@ func (fh *ReadFileHandle) Seek(offset int64, whence int) (n int64, err error) {
if fh.noSeek { if fh.noSeek {
return 0, ESPIPE return 0, ESPIPE
} }
size := fh.o.Size() size := fh.size
switch whence { switch whence {
case 0: case 0:
fh.roffset = 0 fh.roffset = 0
@ -201,8 +203,8 @@ func (fh *ReadFileHandle) readAt(p []byte, off int64) (n int, err error) {
// Are we attempting to seek beyond the end of the // Are we attempting to seek beyond the end of the
// file - if so just return EOF leaving the underlying // file - if so just return EOF leaving the underlying
// file in an unchanged state. // file in an unchanged state.
if off >= fh.o.Size() { if off >= fh.size {
fs.Debugf(fh.o, "ReadFileHandle.Read attempt to read beyond end of file: %d > %d", off, fh.o.Size()) fs.Debugf(fh.o, "ReadFileHandle.Read attempt to read beyond end of file: %d > %d", off, fh.size)
return 0, io.EOF return 0, io.EOF
} }
// Otherwise do the seek // Otherwise do the seek
@ -221,7 +223,7 @@ func (fh *ReadFileHandle) readAt(p []byte, off int64) (n int, err error) {
// } // }
if err == nil { if err == nil {
break break
} else if (err == io.ErrUnexpectedEOF || err == io.EOF) && newOffset == fh.o.Size() { } else if (err == io.ErrUnexpectedEOF || err == io.EOF) && newOffset == fh.size {
// Have read to end of file - reset error // Have read to end of file - reset error
err = nil err = nil
break break
@ -258,7 +260,7 @@ func (fh *ReadFileHandle) readAt(p []byte, off int64) (n int, err error) {
} }
func (fh *ReadFileHandle) checkHash() error { func (fh *ReadFileHandle) checkHash() error {
if fh.hash == nil || !fh.readCalled || fh.offset < fh.o.Size() { if fh.hash == nil || !fh.readCalled || fh.offset < fh.size {
return nil return nil
} }
@ -301,7 +303,7 @@ func (fh *ReadFileHandle) checkHash() error {
func (fh *ReadFileHandle) Read(p []byte) (n int, err error) { func (fh *ReadFileHandle) Read(p []byte) (n int, err error) {
fh.mu.Lock() fh.mu.Lock()
defer fh.mu.Unlock() defer fh.mu.Unlock()
if fh.roffset >= fh.o.Size() { if fh.roffset >= fh.size {
return 0, io.EOF return 0, io.EOF
} }
n, err = fh.readAt(p, fh.roffset) n, err = fh.readAt(p, fh.roffset)
@ -390,7 +392,7 @@ func (fh *ReadFileHandle) Release() error {
func (fh *ReadFileHandle) Size() int64 { func (fh *ReadFileHandle) Size() int64 {
fh.mu.Lock() fh.mu.Lock()
defer fh.mu.Unlock() defer fh.mu.Unlock()
return fh.o.Size() return fh.size
} }
// Stat returns info about the file // Stat returns info about the file