Fix -idle unmounting despite activity
Fixes https://github.com/rfjakob/gocryptfs/issues/421
This commit is contained in:
parent
ce13851bbf
commit
0a4db7d9e9
@ -6,6 +6,7 @@ package fusefrontend
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -50,11 +51,11 @@ type FS struct {
|
|||||||
// "gocryptfs -fsck" reads from the channel to also catch these transparently-
|
// "gocryptfs -fsck" reads from the channel to also catch these transparently-
|
||||||
// mitigated corruptions.
|
// mitigated corruptions.
|
||||||
MitigatedCorruptions chan string
|
MitigatedCorruptions chan string
|
||||||
// Track accesses to the filesystem so that we can know when to autounmount.
|
// This flag is set to zero each time fs.isFiltered() is called
|
||||||
// An access is considered to have happened on every call to encryptPath,
|
// (uint32 so that it can be reset with CompareAndSwapUint32).
|
||||||
// which is called as part of every filesystem operation.
|
// When -idle was used when mounting, idleMonitor() sets it to 1
|
||||||
// (This flag uses a uint32 so that it can be reset with CompareAndSwapUint32.)
|
// periodically.
|
||||||
AccessedSinceLastCheck uint32
|
IsIdle uint32
|
||||||
|
|
||||||
dirCache dirCacheStruct
|
dirCache dirCacheStruct
|
||||||
}
|
}
|
||||||
@ -662,6 +663,8 @@ func (fs *FS) reportMitigatedCorruption(item string) {
|
|||||||
//
|
//
|
||||||
// Prevents name clashes with internal files when file names are not encrypted
|
// Prevents name clashes with internal files when file names are not encrypted
|
||||||
func (fs *FS) isFiltered(path string) bool {
|
func (fs *FS) isFiltered(path string) bool {
|
||||||
|
atomic.StoreUint32(&fs.IsIdle, 0)
|
||||||
|
|
||||||
if !fs.args.PlaintextNames {
|
if !fs.args.PlaintextNames {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
10
mount.go
10
mount.go
@ -181,18 +181,18 @@ func idleMonitor(idleTimeout time.Duration, fs *fusefrontend.FS, srv *fuse.Serve
|
|||||||
timeoutCycles := int(math.Ceil(float64(idleTimeout) / float64(sleepTimeBetweenChecks)))
|
timeoutCycles := int(math.Ceil(float64(idleTimeout) / float64(sleepTimeBetweenChecks)))
|
||||||
idleCount := 0
|
idleCount := 0
|
||||||
for {
|
for {
|
||||||
// Atomically check whether the access flag is set and reset it to 0 if so.
|
// Atomically check whether the flag is 0 and reset it to 1 if so.
|
||||||
recentAccess := atomic.CompareAndSwapUint32(&fs.AccessedSinceLastCheck, 1, 0)
|
isIdle := !atomic.CompareAndSwapUint32(&fs.IsIdle, 0, 1)
|
||||||
// Any form of current or recent access resets the idle counter.
|
// Any form of current or recent access resets the idle counter.
|
||||||
openFileCount := openfiletable.CountOpenFiles()
|
openFileCount := openfiletable.CountOpenFiles()
|
||||||
if recentAccess || openFileCount > 0 {
|
if !isIdle || openFileCount > 0 {
|
||||||
idleCount = 0
|
idleCount = 0
|
||||||
} else {
|
} else {
|
||||||
idleCount++
|
idleCount++
|
||||||
}
|
}
|
||||||
tlog.Debug.Printf(
|
tlog.Debug.Printf(
|
||||||
"Checking for idle (recentAccess = %t, open = %d): %s",
|
"Checking for idle (isIdle = %t, open = %d): %s",
|
||||||
recentAccess, openFileCount, time.Now().String())
|
isIdle, openFileCount, time.Now().String())
|
||||||
if idleCount > 0 && idleCount%timeoutCycles == 0 {
|
if idleCount > 0 && idleCount%timeoutCycles == 0 {
|
||||||
tlog.Info.Printf("Filesystem idle; unmounting: %s", mountpoint)
|
tlog.Info.Printf("Filesystem idle; unmounting: %s", mountpoint)
|
||||||
unmount(srv, mountpoint)
|
unmount(srv, mountpoint)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user