func findPathRootId(dir *C.DIR) (uint64, error) { fd := getDirFd(dir) var args C.struct_btrfs_ioctl_ino_lookup_args args.objectid = C.BTRFS_FIRST_FREE_OBJECTID _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, C.BTRFS_IOC_INO_LOOKUP, uintptr(unsafe.Pointer(&args))) if errno != 0 { return 0, fmt.Errorf("Failed to perform the inode lookup %v", errno.Error()) } return uint64(args.treeid), nil }
func (ila *inodeLookupArgs) C() C.struct_btrfs_ioctl_ino_lookup_args { var args C.struct_btrfs_ioctl_ino_lookup_args args.objectid = C.__u64(ila.ObjectID) args.treeid = C.__u64(ila.TreeID) if ila.Name != "" { str := [C.BTRFS_INO_LOOKUP_PATH_MAX]C.char{} for i := 0; i < len(ila.Name) && i < C.BTRFS_INO_LOOKUP_PATH_MAX; i++ { str[i] = C.char(ila.Name[i]) } args.name = str } return args }
func inodeLookup(dirpath string) (*inodeLookupArgs, error) { dir, err := openDir(dirpath) if err != nil { return nil, err } defer closeDir(dir) var inoArgs C.struct_btrfs_ioctl_ino_lookup_args inoArgs.objectid = C.BTRFS_FIRST_FREE_OBJECTID _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, getDirFd(dir), C.BTRFS_IOC_INO_LOOKUP, uintptr(unsafe.Pointer(&inoArgs))) if errno != 0 { return nil, fmt.Errorf("Failed to lookup btrfs inode: %v", errno.Error()) } return newInodeLookupArgs(inoArgs), nil }
func findRootGen(dir *C.DIR) (uint64, error) { fd := getDirFd(dir) var maxFound uint64 = 0 var inoArgs C.struct_btrfs_ioctl_ino_lookup_args var args C.struct_btrfs_ioctl_search_args var sk *C.struct_btrfs_ioctl_search_key = &args.key var sh C.struct_btrfs_ioctl_search_header inoArgs.objectid = C.BTRFS_FIRST_FREE_OBJECTID _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, C.BTRFS_IOC_INO_LOOKUP, uintptr(unsafe.Pointer(&inoArgs))) if errno != 0 { return 0, fmt.Errorf("Failed to perform the inode lookup %v", errno.Error()) } sk.tree_id = 1 sk.min_objectid = inoArgs.treeid sk.max_objectid = inoArgs.treeid sk.max_type = C.BTRFS_ROOT_ITEM_KEY sk.min_type = C.BTRFS_ROOT_ITEM_KEY sk.max_offset = math.MaxUint64 sk.max_transid = math.MaxUint64 sk.nr_items = 4096 for { _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, C.BTRFS_IOC_TREE_SEARCH, uintptr(unsafe.Pointer(&args))) if errno != 0 { return 0, fmt.Errorf("Failed to perform the search %v", errno.Error()) } if sk.nr_items == 0 { break } var off uintptr = 0 for i := C.__u32(0); i < sk.nr_items; i++ { var item *C.struct_btrfs_root_item C.memcpy(unsafe.Pointer(&sh), addptr(unsafe.Pointer(&args.buf), off), C.sizeof_struct_btrfs_ioctl_search_header) off += C.sizeof_struct_btrfs_ioctl_search_header item = (*C.struct_btrfs_root_item)(unsafe.Pointer(&args.buf[off])) off += uintptr(sh.len) sk.min_objectid = sh.objectid sk.min_type = sh._type sk.min_offset = sh.offset if sh.objectid > inoArgs.treeid { break } if sh.objectid == inoArgs.treeid && sh._type == C.BTRFS_ROOT_ITEM_KEY { rootGeneration := item.generation if maxFound < uint64(rootGeneration) { maxFound = uint64(rootGeneration) } } } if sk.min_offset < math.MaxUint64 { sk.min_offset++ } else { break } if sk.min_type != C.BTRFS_ROOT_ITEM_KEY { break } if sk.min_objectid != inoArgs.treeid { break } } return maxFound, nil }