From 29d34426bc2ced9ca6ad083ac6f67d85b942e4b1 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 15 Dec 2017 15:42:49 +0000 Subject: [PATCH] vfs: fix deletion of in use directories #1860 This was causing errors if the cache cleaner was called between the Open and the pendingOpen of a RW file. The fix was to move the cache open to the Open from the openPending. --- vfs/cache.go | 3 +++ vfs/read_write.go | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/vfs/cache.go b/vfs/cache.go index 7a5d68ac1..838f37f20 100644 --- a/vfs/cache.go +++ b/vfs/cache.go @@ -267,6 +267,9 @@ func (c *cache) removeDir(dir string) bool { osPath := c.toOSPath(dir) err := os.Remove(osPath) if err == nil || os.IsNotExist(err) { + if err == nil { + fs.Debugf(dir, "Removed empty directory") + } return true } if !os.IsExist(err) { diff --git a/vfs/read_write.go b/vfs/read_write.go index d13218a36..c95e26381 100644 --- a/vfs/read_write.go +++ b/vfs/read_write.go @@ -39,12 +39,6 @@ var ( ) func newRWFileHandle(d *Dir, f *File, remote string, flags int) (fh *RWFileHandle, err error) { - // Make a place for the file - osPath, err := d.vfs.cache.mkdir(remote) - if err != nil { - return nil, errors.Wrap(err, "open RW handle failed to make cache directory") - } - // if O_CREATE and O_EXCL are set and if path already exists, then return EEXIST if flags&(os.O_CREATE|os.O_EXCL) == os.O_CREATE|os.O_EXCL && f.exists() { return nil, EEXIST @@ -56,7 +50,16 @@ func newRWFileHandle(d *Dir, f *File, remote string, flags int) (fh *RWFileHandl d: d, remote: remote, flags: flags, - osPath: osPath, + } + + // mark the file as open in the cache - must be done before the mkdir + fh.d.vfs.cache.open(fh.remote) + + // Make a place for the file + fh.osPath, err = d.vfs.cache.mkdir(remote) + if err != nil { + fh.d.vfs.cache.close(fh.remote) + return nil, errors.Wrap(err, "open RW handle failed to make cache directory") } rdwrMode := fh.flags & accessModeMask @@ -129,7 +132,6 @@ func (fh *RWFileHandle) openPending(truncate bool) (err error) { } fh.File = fd fh.opened = true - fh.d.vfs.cache.open(fh.remote) fh.d.addObject(fh.file) // make sure the directory has this object in it now return nil } @@ -167,6 +169,7 @@ func (fh *RWFileHandle) close() (err error) { return ECLOSED } fh.closed = true + defer fh.d.vfs.cache.close(fh.remote) rdwrMode := fh.flags & accessModeMask if rdwrMode != os.O_RDONLY { // leave writer open until file is transferred @@ -196,7 +199,6 @@ func (fh *RWFileHandle) close() (err error) { fh.file.setSize(fi.Size()) } } - fh.d.vfs.cache.close(fh.remote) // Close the underlying file err = fh.File.Close()