87 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package btrfs
 | 
						|
 | 
						|
/*
 | 
						|
#include <stddef.h>
 | 
						|
#include <btrfs/ioctl.h>
 | 
						|
#include <btrfs/ctree.h>
 | 
						|
*/
 | 
						|
import "C"
 | 
						|
 | 
						|
import (
 | 
						|
	"bufio"
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"strings"
 | 
						|
	"unsafe"
 | 
						|
 | 
						|
	"github.com/pkg/errors"
 | 
						|
)
 | 
						|
 | 
						|
func subvolID(fd uintptr) (uint64, error) {
 | 
						|
	var args C.struct_btrfs_ioctl_ino_lookup_args
 | 
						|
	args.objectid = C.BTRFS_FIRST_FREE_OBJECTID
 | 
						|
 | 
						|
	if err := ioctl(fd, C.BTRFS_IOC_INO_LOOKUP, uintptr(unsafe.Pointer(&args))); err != nil {
 | 
						|
		return 0, err
 | 
						|
	}
 | 
						|
 | 
						|
	return uint64(args.treeid), nil
 | 
						|
}
 | 
						|
 | 
						|
var (
 | 
						|
	zeroArray = [16]byte{}
 | 
						|
	zeros     = zeroArray[:]
 | 
						|
)
 | 
						|
 | 
						|
func uuidString(uuid *[C.BTRFS_UUID_SIZE]C.u8) string {
 | 
						|
	b := (*[1<<31 - 1]byte)(unsafe.Pointer(uuid))[:C.BTRFS_UUID_SIZE]
 | 
						|
 | 
						|
	if bytes.Equal(b, zeros) {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
 | 
						|
	return fmt.Sprintf("%x-%x-%x-%x-%x", b[:4], b[4:4+2], b[6:6+2], b[8:8+2], b[10:16])
 | 
						|
}
 | 
						|
 | 
						|
func findMountPoint(path string) (string, error) {
 | 
						|
	fp, err := os.Open("/proc/self/mounts")
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	defer fp.Close()
 | 
						|
 | 
						|
	const (
 | 
						|
		deviceIdx = 0
 | 
						|
		pathIdx   = 1
 | 
						|
		typeIdx   = 2
 | 
						|
		options   = 3
 | 
						|
	)
 | 
						|
 | 
						|
	var (
 | 
						|
		mount   string
 | 
						|
		scanner = bufio.NewScanner(fp)
 | 
						|
	)
 | 
						|
 | 
						|
	for scanner.Scan() {
 | 
						|
		fields := strings.Fields(scanner.Text())
 | 
						|
		if fields[typeIdx] != "btrfs" {
 | 
						|
			continue // skip non-btrfs
 | 
						|
		}
 | 
						|
 | 
						|
		if strings.HasPrefix(path, fields[pathIdx]) {
 | 
						|
			mount = fields[pathIdx]
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if scanner.Err() != nil {
 | 
						|
		return "", scanner.Err()
 | 
						|
	}
 | 
						|
 | 
						|
	if mount == "" {
 | 
						|
		return "", errors.Errorf("mount point of %v not found", path)
 | 
						|
	}
 | 
						|
 | 
						|
	return mount, nil
 | 
						|
}
 |