From 51c421d91172e87df30bd344b3fd3142bc388718 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 18 Jan 2022 23:43:35 -0800 Subject: 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 --- filesystem/mountpoint.go | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'filesystem') 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 -- cgit v1.2.3