blob: 5a27144db59b4b53ead47c28887eb3b5fedba9bf [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// +build linux,darwin,unix !windows !fuchsia
package gpt
import (
"os"
"syscall"
"unsafe"
)
func ioctl(fd, op, v uintptr) error {
_, _, er := syscall.Syscall(syscall.SYS_IOCTL, fd, op, v)
if er != 0 {
return os.NewSyscallError("ioctl", er)
}
return nil
}
// GetPhysicalBlockSize fetches the physical block size of the given file. It
// requires elevated process priviliges to execute on most platforms. Currently
// only supported on Linux and Darwin.
func GetPhysicalBlockSize(f *os.File) (uint64, error) {
if _, regular := regularSize(f); regular {
return FallbackPhysicalBlockSize, nil
}
var sz uint32
if err := ioctl(uintptr(f.Fd()), IOCTLPhysical, uintptr(unsafe.Pointer(&sz))); err != nil {
return FallbackPhysicalBlockSize, err
}
return uint64(sz), nil
}
// GetLogicalBlockSize fetches the physical block size of the given file. It
// requires elevated process priviliges to execute on most platforms. Currently
// only supported on Linux and Darwin.
func GetLogicalBlockSize(f *os.File) (uint64, error) {
if _, regular := regularSize(f); regular {
return FallbackLogicalBlockSize, nil
}
var sz uint32
if err := ioctl(uintptr(f.Fd()), IOCTLLogical, uintptr(unsafe.Pointer(&sz))); err != nil {
return FallbackLogicalBlockSize, err
}
return uint64(sz), nil
}
// GetDiskSize fetches the byte size of the given disk.
func GetDiskSize(f *os.File) (uint64, error) {
if sz, regular := regularSize(f); regular {
return uint64(sz), nil
}
var sz uint64
if err := ioctl(uintptr(f.Fd()), IOCTLSize, uintptr(unsafe.Pointer(&sz))); err != nil {
return 0, err
}
lbs, err := GetLogicalBlockSize(f)
if err != nil {
return 0, err
}
return uint64(lbs) * sz, nil
}