diff options
author | Jakob Unterwurzacher | 2019-09-08 16:29:20 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2019-09-08 16:29:20 +0200 |
commit | 0a4db7d9e9801a416602b52281537991ba1463c0 (patch) | |
tree | 396f3786cd0186e1c0f592512fc4adac5fed0b5a | |
parent | ce13851bbfceb02da0b36e743090c5fe54469b33 (diff) |
Fix -idle unmounting despite activity
Fixes https://github.com/rfjakob/gocryptfs/issues/421
-rw-r--r-- | internal/fusefrontend/fs.go | 13 | ||||
-rw-r--r-- | mount.go | 10 |
2 files changed, 13 insertions, 10 deletions
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 2c40942..fe37d10 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -6,6 +6,7 @@ package fusefrontend import ( "os" "sync" + "sync/atomic" "syscall" "time" @@ -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 } @@ -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 } @@ -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) |