diff options
| author | Joseph Richey <joerichey@google.com> | 2019-10-30 22:49:40 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-30 22:49:40 +0100 |
| commit | 9b2f1c37fc881d7e991cf0b8abab662d4bf9055c (patch) | |
| tree | c41774c7422e3cb5e55a753c79d4c45fe3692501 /filesystem/path.go | |
| parent | a3434e41bd482fc1b35703f66c24c9d1ec3b0be2 (diff) | |
| parent | e71c5e4f70632b99a08d127b35e80a9e291e1938 (diff) | |
Merge pull request #154 from ebiggers/bind-mounts
Store fscrypt metadata in only one place per filesystem, so that bind
mounts don't get their own metadata directories (which was ambiguous,
as the same file may be accessible via multiple mounts).
Also correctly set the source device for root filesystems mounted via
the kernel command line, and fix creating linked protectors to such
filesystems.
Diffstat (limited to 'filesystem/path.go')
| -rw-r--r-- | filesystem/path.go | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/filesystem/path.go b/filesystem/path.go index cfc3dc0..376daf0 100644 --- a/filesystem/path.go +++ b/filesystem/path.go @@ -20,6 +20,7 @@ package filesystem import ( + "fmt" "log" "os" "path/filepath" @@ -72,12 +73,6 @@ func isDir(path string) bool { return err == nil && info.IsDir() } -// isDevice returns true if the path exists and is that of a device. -func isDevice(path string) bool { - info, err := loggedStat(path) - return err == nil && info.Mode()&os.ModeDevice != 0 -} - // isDirCheckPerm returns true if the path exists and is a directory. If the // specified permissions and sticky bit of mode do not match the path, an error // is logged. @@ -99,3 +94,38 @@ func isRegularFile(path string) bool { info, err := loggedStat(path) return err == nil && info.Mode().IsRegular() } + +// DeviceNumber represents a combined major:minor device number. +type DeviceNumber uint64 + +func (num DeviceNumber) String() string { + return fmt.Sprintf("%d:%d", unix.Major(uint64(num)), unix.Minor(uint64(num))) +} + +func newDeviceNumberFromString(str string) (DeviceNumber, error) { + var major, minor uint32 + if count, _ := fmt.Sscanf(str, "%d:%d", &major, &minor); count != 2 { + return 0, errors.Errorf("invalid device number string %q", str) + } + return DeviceNumber(unix.Mkdev(major, minor)), nil +} + +// getDeviceNumber returns the device number of the device node at the given +// path. If there is a symlink at the path, it is dereferenced. +func getDeviceNumber(path string) (DeviceNumber, error) { + var stat unix.Stat_t + if err := unix.Stat(path, &stat); err != nil { + return 0, err + } + return DeviceNumber(stat.Rdev), nil +} + +// getNumberOfContainingDevice returns the device number of the filesystem which +// contains the given file. If the file is a symlink, it is not dereferenced. +func getNumberOfContainingDevice(path string) (DeviceNumber, error) { + var stat unix.Stat_t + if err := unix.Lstat(path, &stat); err != nil { + return 0, err + } + return DeviceNumber(stat.Dev), nil +} |