aboutsummaryrefslogtreecommitdiff
path: root/filesystem/mountpoint.go
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2022-01-18 23:43:35 -0800
committerEric Biggers <ebiggers@google.com>2022-01-26 23:22:55 -0800
commit51c421d91172e87df30bd344b3fd3142bc388718 (patch)
treea0855bd039ed79055b8cb63026a0c9ef19a3ec2a /filesystem/mountpoint.go
parent65a445d4d01c09f43676180d779abbff0de40f1e (diff)
filesystem: make FindMount() fall back to search by path
This is needed to make FindMount() work on btrfs filesystems. Update https://github.com/google/fscrypt/issues/339
Diffstat (limited to 'filesystem/mountpoint.go')
-rw-r--r--filesystem/mountpoint.go30
1 files changed, 25 insertions, 5 deletions
diff --git a/filesystem/mountpoint.go b/filesystem/mountpoint.go
index a4c1ec1..20a8568 100644
--- a/filesystem/mountpoint.go
+++ b/filesystem/mountpoint.go
@@ -364,18 +364,38 @@ func FindMount(path string) (*Mount, error) {
if err := loadMountInfo(); err != nil {
return nil, err
}
+ // First try to find the mount by the number of the containing device.
deviceNumber, err := getNumberOfContainingDevice(path)
if err != nil {
return nil, err
}
mnt, ok := mountsByDevice[deviceNumber]
- if !ok {
- return nil, errors.Errorf("couldn't find mountpoint containing %q", path)
+ if ok {
+ if mnt == nil {
+ return nil, filesystemLacksMainMountError(deviceNumber)
+ }
+ return mnt, nil
}
- if mnt == nil {
- return nil, filesystemLacksMainMountError(deviceNumber)
+ // The mount couldn't be found by the number of the containing device.
+ // Fall back to walking up the directory hierarchy and checking for a
+ // mount at each directory path. This is necessary for btrfs, where
+ // files report a different st_dev from the /proc/self/mountinfo entry.
+ curPath, err := canonicalizePath(path)
+ if err != nil {
+ return nil, err
+ }
+ for {
+ mnt := mountsByPath[curPath]
+ if mnt != nil {
+ return mnt, nil
+ }
+ // Move to the parent directory unless we have reached the root.
+ parent := filepath.Dir(curPath)
+ if parent == curPath {
+ return nil, errors.Errorf("couldn't find mountpoint containing %q", path)
+ }
+ curPath = parent
}
- return mnt, nil
}
// GetMount is like FindMount, except GetMount also returns an error if the path