Skip to content

Commit

Permalink
Prevent removal of the directory from cache while it has open files
Browse files Browse the repository at this point in the history
(Because an open file may easily become modified at any point)
  • Loading branch information
vitalif committed Sep 21, 2021
1 parent ba7f5e4 commit 8ad5d3b
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 6 deletions.
8 changes: 4 additions & 4 deletions internal/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func (dh *DirHandle) listObjectsFlat() (err error) {
cloud, prefix := dh.inode.cloud()
if cloud == nil {
// Stale inode
return fuse.ENOENT
return syscall.ESTALE
}
if dh.inode.oldParent != nil {
_, prefix = dh.inode.oldParent.cloud()
Expand Down Expand Up @@ -1254,7 +1254,7 @@ func (inode *Inode) SetCacheState(state int32) {
wasModified := inode.CacheState == ST_CREATED || inode.CacheState == ST_DELETED || inode.CacheState == ST_MODIFIED
willBeModified := state == ST_CREATED || state == ST_DELETED || state == ST_MODIFIED
atomic.StoreInt32(&inode.CacheState, state)
if wasModified != willBeModified {
if wasModified != willBeModified && (inode.isDir() || inode.fileHandles == 0) {
inc := int64(1)
if wasModified {
inc = -1
Expand Down Expand Up @@ -1424,7 +1424,7 @@ func renameInCache(fromInode *Inode, newParent *Inode, to string) {
parent.dir.DeletedChildren = make(map[string]*Inode)
}
parent.dir.DeletedChildren[fromInode.Name] = fromInode
if fromInode.CacheState == ST_CACHED {
if fromInode.CacheState == ST_CACHED && (fromInode.isDir() || fromInode.fileHandles == 0) {
// Was not modified and we remove it from current parent => add modified
parent.addModified(1)
}
Expand Down Expand Up @@ -1459,7 +1459,7 @@ func renameInCache(fromInode *Inode, newParent *Inode, to string) {
parent.removeChildUnlocked(fromInode)
fromInode.Name = to
fromInode.Parent = newParent
if fromInode.CacheState == ST_CACHED {
if fromInode.CacheState == ST_CACHED && (fromInode.isDir() || fromInode.fileHandles == 0) {
// Was not modified => we make it modified
fromInode.SetCacheState(ST_MODIFIED)
} else {
Expand Down
4 changes: 3 additions & 1 deletion internal/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,9 @@ func (fh *FileHandle) Release() {
if n == -1 {
panic(fmt.Sprintf("Released more file handles than acquired, n = %v", n))
}

if n == 0 && atomic.LoadInt32(&fh.inode.CacheState) == ST_CACHED {
fh.inode.Parent.addModified(-1)
}
fh.inode.fs.WakeupFlusher()
}

Expand Down
5 changes: 4 additions & 1 deletion internal/handles.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,9 @@ func (inode *Inode) OpenFile() (fh *FileHandle, err error) {

fh = NewFileHandle(inode)

atomic.AddInt32(&inode.fileHandles, 1)
n := atomic.AddInt32(&inode.fileHandles, 1)
if n == 1 && inode.CacheState == ST_CACHED {
inode.Parent.addModified(1)
}
return
}

0 comments on commit 8ad5d3b

Please sign in to comment.