diff options
Diffstat (limited to 'filesystem/mountpoint.go')
| -rw-r--r-- | filesystem/mountpoint.go | 30 |
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 |