Skip to content

Commit

Permalink
Fix -idle unmounting despite activity
Browse files Browse the repository at this point in the history
Fixes #421
  • Loading branch information
rfjakob committed Sep 8, 2019
1 parent ce13851 commit 0a4db7d
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 10 deletions.
13 changes: 8 additions & 5 deletions internal/fusefrontend/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package fusefrontend
import (
"os"
"sync"
"sync/atomic"
"syscall"
"time"

Expand Down Expand Up @@ -50,11 +51,11 @@ type FS struct {
// "gocryptfs -fsck" reads from the channel to also catch these transparently-
// mitigated corruptions.
MitigatedCorruptions chan string
// Track accesses to the filesystem so that we can know when to autounmount.
// An access is considered to have happened on every call to encryptPath,
// which is called as part of every filesystem operation.
// (This flag uses a uint32 so that it can be reset with CompareAndSwapUint32.)
AccessedSinceLastCheck uint32
// This flag is set to zero each time fs.isFiltered() is called
// (uint32 so that it can be reset with CompareAndSwapUint32).
// When -idle was used when mounting, idleMonitor() sets it to 1
// periodically.
IsIdle uint32

dirCache dirCacheStruct
}
Expand Down Expand Up @@ -662,6 +663,8 @@ func (fs *FS) reportMitigatedCorruption(item string) {
//
// Prevents name clashes with internal files when file names are not encrypted
func (fs *FS) isFiltered(path string) bool {
atomic.StoreUint32(&fs.IsIdle, 0)

if !fs.args.PlaintextNames {
return false
}
Expand Down
10 changes: 5 additions & 5 deletions mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,18 +181,18 @@ func idleMonitor(idleTimeout time.Duration, fs *fusefrontend.FS, srv *fuse.Serve
timeoutCycles := int(math.Ceil(float64(idleTimeout) / float64(sleepTimeBetweenChecks)))
idleCount := 0
for {
// Atomically check whether the access flag is set and reset it to 0 if so.
recentAccess := atomic.CompareAndSwapUint32(&fs.AccessedSinceLastCheck, 1, 0)
// Atomically check whether the flag is 0 and reset it to 1 if so.
isIdle := !atomic.CompareAndSwapUint32(&fs.IsIdle, 0, 1)
// Any form of current or recent access resets the idle counter.
openFileCount := openfiletable.CountOpenFiles()
if recentAccess || openFileCount > 0 {
if !isIdle || openFileCount > 0 {
idleCount = 0
} else {
idleCount++
}
tlog.Debug.Printf(
"Checking for idle (recentAccess = %t, open = %d): %s",
recentAccess, openFileCount, time.Now().String())
"Checking for idle (isIdle = %t, open = %d): %s",
isIdle, openFileCount, time.Now().String())
if idleCount > 0 && idleCount%timeoutCycles == 0 {
tlog.Info.Printf("Filesystem idle; unmounting: %s", mountpoint)
unmount(srv, mountpoint)
Expand Down

0 comments on commit 0a4db7d

Please sign in to comment.