forked from TrueCloudLab/rclone
vfs: Make sure all public methods are locked in Read and Write Handle
This commit is contained in:
parent
2083ac6e2a
commit
c31556c6d1
2 changed files with 43 additions and 9 deletions
33
vfs/read.go
33
vfs/read.go
|
@ -73,6 +73,8 @@ func (fh *ReadFileHandle) String() string {
|
||||||
if fh == nil {
|
if fh == nil {
|
||||||
return "<nil *ReadFileHandle>"
|
return "<nil *ReadFileHandle>"
|
||||||
}
|
}
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
if fh.file == nil {
|
if fh.file == nil {
|
||||||
return "<nil *ReadFileHandle.file>"
|
return "<nil *ReadFileHandle.file>"
|
||||||
}
|
}
|
||||||
|
@ -81,6 +83,8 @@ func (fh *ReadFileHandle) String() string {
|
||||||
|
|
||||||
// Node returns the Node assocuated with this - satisfies Noder interface
|
// Node returns the Node assocuated with this - satisfies Noder interface
|
||||||
func (fh *ReadFileHandle) Node() Node {
|
func (fh *ReadFileHandle) Node() Node {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
return fh.file
|
return fh.file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +130,8 @@ func (fh *ReadFileHandle) seek(offset int64, reopen bool) (err error) {
|
||||||
|
|
||||||
// Seek the file - returns ESPIPE if seeking isn't possible
|
// Seek the file - returns ESPIPE if seeking isn't possible
|
||||||
func (fh *ReadFileHandle) Seek(offset int64, whence int) (n int64, err error) {
|
func (fh *ReadFileHandle) Seek(offset int64, whence int) (n int64, err error) {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
if fh.noSeek {
|
if fh.noSeek {
|
||||||
return 0, ESPIPE
|
return 0, ESPIPE
|
||||||
}
|
}
|
||||||
|
@ -168,6 +174,11 @@ func (fh *ReadFileHandle) Seek(offset int64, whence int) (n int64, err error) {
|
||||||
func (fh *ReadFileHandle) ReadAt(p []byte, off int64) (n int, err error) {
|
func (fh *ReadFileHandle) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
fh.mu.Lock()
|
fh.mu.Lock()
|
||||||
defer fh.mu.Unlock()
|
defer fh.mu.Unlock()
|
||||||
|
return fh.readAt(p, off)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of ReadAt - call with lock held
|
||||||
|
func (fh *ReadFileHandle) readAt(p []byte, off int64) (n int, err error) {
|
||||||
err = fh.openPending() // FIXME pending open could be more efficient in the presense of seek (and retries)
|
err = fh.openPending() // FIXME pending open could be more efficient in the presense of seek (and retries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -291,10 +302,12 @@ func (fh *ReadFileHandle) checkHash() error {
|
||||||
//
|
//
|
||||||
// Implementations must not retain p.
|
// Implementations must not retain p.
|
||||||
func (fh *ReadFileHandle) Read(p []byte) (n int, err error) {
|
func (fh *ReadFileHandle) Read(p []byte) (n int, err error) {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
if fh.roffset >= fh.o.Size() {
|
if fh.roffset >= fh.o.Size() {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
n, err = fh.ReadAt(p, fh.roffset)
|
n, err = fh.readAt(p, fh.roffset)
|
||||||
fh.roffset += int64(n)
|
fh.roffset += int64(n)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
@ -311,13 +324,15 @@ func (fh *ReadFileHandle) close() error {
|
||||||
|
|
||||||
if fh.opened {
|
if fh.opened {
|
||||||
fs.Stats.DoneTransferring(fh.o.Remote(), true)
|
fs.Stats.DoneTransferring(fh.o.Remote(), true)
|
||||||
err1 := fh.checkHash()
|
// Close first so that we have hashes
|
||||||
err2 := fh.r.Close()
|
err := fh.r.Close()
|
||||||
if err1 != nil {
|
if err != nil {
|
||||||
return err1
|
return err
|
||||||
}
|
}
|
||||||
if err2 != nil {
|
// Now check the hash
|
||||||
return err2
|
err = fh.checkHash()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -376,10 +391,14 @@ func (fh *ReadFileHandle) Release() error {
|
||||||
|
|
||||||
// Size returns the size of the underlying file
|
// Size returns the size of the underlying file
|
||||||
func (fh *ReadFileHandle) Size() int64 {
|
func (fh *ReadFileHandle) Size() int64 {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
return fh.o.Size()
|
return fh.o.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat returns info about the file
|
// Stat returns info about the file
|
||||||
func (fh *ReadFileHandle) Stat() (os.FileInfo, error) {
|
func (fh *ReadFileHandle) Stat() (os.FileInfo, error) {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
return fh.file, nil
|
return fh.file, nil
|
||||||
}
|
}
|
||||||
|
|
19
vfs/write.go
19
vfs/write.go
|
@ -59,6 +59,8 @@ func (fh *WriteFileHandle) String() string {
|
||||||
if fh == nil {
|
if fh == nil {
|
||||||
return "<nil *WriteFileHandle>"
|
return "<nil *WriteFileHandle>"
|
||||||
}
|
}
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
if fh.file == nil {
|
if fh.file == nil {
|
||||||
return "<nil *WriteFileHandle.file>"
|
return "<nil *WriteFileHandle.file>"
|
||||||
}
|
}
|
||||||
|
@ -67,6 +69,8 @@ func (fh *WriteFileHandle) String() string {
|
||||||
|
|
||||||
// Node returns the Node assocuated with this - satisfies Noder interface
|
// Node returns the Node assocuated with this - satisfies Noder interface
|
||||||
func (fh *WriteFileHandle) Node() Node {
|
func (fh *WriteFileHandle) Node() Node {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
return fh.file
|
return fh.file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,9 +87,14 @@ func (fh *WriteFileHandle) Node() Node {
|
||||||
//
|
//
|
||||||
// Implementations must not retain p.
|
// Implementations must not retain p.
|
||||||
func (fh *WriteFileHandle) WriteAt(p []byte, off int64) (n int, err error) {
|
func (fh *WriteFileHandle) WriteAt(p []byte, off int64) (n int, err error) {
|
||||||
// fs.Debugf(fh.remote, "WriteFileHandle.Write len=%d", len(p))
|
|
||||||
fh.mu.Lock()
|
fh.mu.Lock()
|
||||||
defer fh.mu.Unlock()
|
defer fh.mu.Unlock()
|
||||||
|
return fh.writeAt(p, off)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementatino of WriteAt - call with lock held
|
||||||
|
func (fh *WriteFileHandle) writeAt(p []byte, off int64) (n int, err error) {
|
||||||
|
// fs.Debugf(fh.remote, "WriteFileHandle.Write len=%d", len(p))
|
||||||
if fh.closed {
|
if fh.closed {
|
||||||
fs.Errorf(fh.remote, "WriteFileHandle.Write error: %v", EBADF)
|
fs.Errorf(fh.remote, "WriteFileHandle.Write error: %v", EBADF)
|
||||||
return 0, ECLOSED
|
return 0, ECLOSED
|
||||||
|
@ -114,12 +123,16 @@ func (fh *WriteFileHandle) WriteAt(p []byte, off int64) (n int, err error) {
|
||||||
//
|
//
|
||||||
// Implementations must not retain p.
|
// Implementations must not retain p.
|
||||||
func (fh *WriteFileHandle) Write(p []byte) (n int, err error) {
|
func (fh *WriteFileHandle) Write(p []byte) (n int, err error) {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
// Since we can't seek, just call WriteAt with the current offset
|
// Since we can't seek, just call WriteAt with the current offset
|
||||||
return fh.WriteAt(p, fh.offset)
|
return fh.writeAt(p, fh.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset returns the offset of the file pointer
|
// Offset returns the offset of the file pointer
|
||||||
func (fh *WriteFileHandle) Offset() (offset int64) {
|
func (fh *WriteFileHandle) Offset() (offset int64) {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
return fh.offset
|
return fh.offset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,5 +224,7 @@ func (fh *WriteFileHandle) Release() error {
|
||||||
|
|
||||||
// Stat returns info about the file
|
// Stat returns info about the file
|
||||||
func (fh *WriteFileHandle) Stat() (os.FileInfo, error) {
|
func (fh *WriteFileHandle) Stat() (os.FileInfo, error) {
|
||||||
|
fh.mu.Lock()
|
||||||
|
defer fh.mu.Unlock()
|
||||||
return fh.file, nil
|
return fh.file, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue