| // 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 |
| } |