diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go index 430f5c2e60..5e055f6dba 100644 --- a/daemon/graphdriver/devmapper/deviceset.go +++ b/daemon/graphdriver/devmapper/deviceset.go @@ -921,11 +921,16 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error { var flags uintptr = syscall.MS_MGC_VAL + fstype, err := ProbeFsType(info.DevName()) + if err != nil { + return err + } + mountOptions := label.FormatMountLabel("discard", mountLabel) - err = syscall.Mount(info.DevName(), path, "ext4", flags, mountOptions) + err = syscall.Mount(info.DevName(), path, fstype, flags, mountOptions) if err != nil && err == syscall.EINVAL { mountOptions = label.FormatMountLabel("", mountLabel) - err = syscall.Mount(info.DevName(), path, "ext4", flags, mountOptions) + err = syscall.Mount(info.DevName(), path, fstype, flags, mountOptions) } if err != nil { return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), path, err) diff --git a/daemon/graphdriver/devmapper/mount.go b/daemon/graphdriver/devmapper/mount.go index 6de9e46c8c..4ec0698c6c 100644 --- a/daemon/graphdriver/devmapper/mount.go +++ b/daemon/graphdriver/devmapper/mount.go @@ -3,6 +3,8 @@ package devmapper import ( + "bytes" + "fmt" "os" "path/filepath" "syscall" @@ -27,3 +29,48 @@ func Mounted(mountpoint string) (bool, error) { parentSt := parent.Sys().(*syscall.Stat_t) return mntpointSt.Dev != parentSt.Dev, nil } + +type probeData struct { + fsName string + magic string + offset uint64 +} + +func ProbeFsType(device string) (string, error) { + probes := []probeData{ + {"btrfs", "_BHRfS_M", 0x10040}, + {"ext4", "\123\357", 0x438}, + {"xfs", "XFSB", 0}, + } + + maxLen := uint64(0) + for _, p := range probes { + l := p.offset + uint64(len(p.magic)) + if l > maxLen { + maxLen = l + } + } + + file, err := os.Open(device) + if err != nil { + return "", err + } + + buffer := make([]byte, maxLen) + l, err := file.Read(buffer) + if err != nil { + return "", err + } + file.Close() + if uint64(l) != maxLen { + return "", fmt.Errorf("unable to detect filesystem type of %s, short read", device) + } + + for _, p := range probes { + if bytes.Equal([]byte(p.magic), buffer[p.offset:p.offset+uint64(len(p.magic))]) { + return p.fsName, nil + } + } + + return "", fmt.Errorf("Unknown filesystem type on %s", device) +}