auto generate ioctl structs and definitions from scoutfs headers

This commit is contained in:
Ben McClelland
2019-06-28 12:17:29 -07:00
parent 16911b5b0a
commit 92e719d578
6 changed files with 227 additions and 374 deletions

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@
*.dll *.dll
*.so *.so
*.dylib *.dylib
_obj
# Test binary, build with `go test -c` # Test binary, build with `go test -c`
*.test *.test

78
c_defs_linux.go Normal file
View File

@@ -0,0 +1,78 @@
// +build ignore
// Copyright (c) 2018 Versity Software, Inc.
//
// Use of this source code is governed by a BSD-3-Clause license
// that can be found in the LICENSE file in the root of the source
// tree.
package scoutfs
// use this to generate the types for scoutfs:
// go tool cgo -godefs c_defs.go >scoutfsdefs.go
// #include <unistd.h>
// #include <stdio.h>
// #include <stdlib.h>
// #include <sys/types.h>
// #include <sys/stat.h>
// #include <sys/ioctl.h>
// #include <fcntl.h>
// #include <errno.h>
// #include <string.h>
// #include <getopt.h>
// #include <ctype.h>
// #include <stdint.h>
// typedef uint8_t __u8;
// typedef uint16_t __u16;
// typedef uint32_t __u32;
// typedef uint64_t __u64;
// typedef uint16_t __le16;
// typedef uint32_t __le32;
// typedef uint64_t __le64;
// typedef int32_t __s32;
// #define __packed
// #include "/usr/include/scoutfs/ioctl.h"
// typedef struct scoutfs_ioctl_walk_inodes_entry scoutfs_ioctl_walk_inodes_entry_t;
// typedef struct scoutfs_ioctl_walk_inodes scoutfs_ioctl_walk_inodes_t;
// typedef struct scoutfs_ioctl_ino_path scoutfs_ioctl_ino_path_t;
// typedef struct scoutfs_ioctl_ino_path_result scoutfs_ioctl_ino_path_result_t;
// typedef struct scoutfs_ioctl_release scoutfs_ioctl_release_t;
// typedef struct scoutfs_ioctl_stage scoutfs_ioctl_stage_t;
// typedef struct scoutfs_ioctl_stat_more scoutfs_ioctl_stat_more_t;
// typedef struct scoutfs_fid scoutfs_fid_t;
// typedef struct scoutfs_ioctl_data_waiting_entry scoutfs_ioctl_data_waiting_entry_t;
// typedef struct scoutfs_ioctl_data_waiting scoutfs_ioctl_data_waiting_t;
// typedef struct scoutfs_ioctl_setattr_more scoutfs_ioctl_setattr_more_t;
// typedef struct scoutfs_ioctl_listxattr_hidden scoutfs_ioctl_listxattr_hidden_t;
// typedef struct scoutfs_ioctl_find_xattrs scoutfs_ioctl_find_xattrs_t;
import "C"
const IOCQUERYINODES = C.SCOUTFS_IOC_WALK_INODES
const IOCINOPATH = C.SCOUTFS_IOC_INO_PATH
const IOCRELEASE = C.SCOUTFS_IOC_RELEASE
const IOCSTAGE = C.SCOUTFS_IOC_STAGE
const IOCSTATMORE = C.SCOUTFS_IOC_STAT_MORE
const IOCDATAWAITING = C.SCOUTFS_IOC_DATA_WAITING
const IOCSETATTRMORE = C.SCOUTFS_IOC_SETATTR_MORE
const IOCLISTXATTRHIDDEN = C.SCOUTFS_IOC_LISTXATTR_HIDDEN
const IOCFINDXATTRS = C.SCOUTFS_IOC_FIND_XATTRS
const QUERYINODESMETASEQ = C.SCOUTFS_IOC_WALK_INODES_META_SEQ
const QUERYINODESDATASEQ = C.SCOUTFS_IOC_WALK_INODES_DATA_SEQ
const DATAWAITOPREAD = C.SCOUTFS_IOC_DWO_READ
const DATAWAITOPWRITE = C.SCOUTFS_IOC_DWO_WRITE
const DATAWAITOPCHANGESIZE = C.SCOUTFS_IOC_DWO_CHANGE_SIZE
type InodesEntry C.scoutfs_ioctl_walk_inodes_entry_t
type queryInodes C.scoutfs_ioctl_walk_inodes_t
type inoPath C.scoutfs_ioctl_ino_path_t
type iocRelease C.scoutfs_ioctl_release_t
type iocStage C.scoutfs_ioctl_stage_t
type Stat C.scoutfs_ioctl_stat_more_t
type DataWaitingEntry C.scoutfs_ioctl_data_waiting_entry_t
type dataWaiting C.scoutfs_ioctl_data_waiting_t
type setattrMore C.scoutfs_ioctl_setattr_more_t
type listXattrHidden C.scoutfs_ioctl_listxattr_hidden_t
type findXattrs C.scoutfs_ioctl_find_xattrs_t

View File

@@ -30,12 +30,12 @@ func main() {
os.Exit(1) os.Exit(1)
} }
f, err := os.Open(os.Args[1]) f, err := os.OpenFile(os.Args[1], os.O_RDWR, 0)
if err != nil { if err != nil {
log.Fatalf("open %v: %v", os.Args[1], err) log.Fatalf("open %v: %v", os.Args[1], err)
} }
lxr := scoutfs.NewListXattrRaw(f) lxr := scoutfs.NewListXattrHidden(f)
for { for {
attrs, err := lxr.Next() attrs, err := lxr.Next()

View File

@@ -16,8 +16,9 @@ import (
) )
const ( const (
max64 = 0xffffffffffffffff max64 = 0xffffffffffffffff
max32 = 0xffffffff max32 = 0xffffffff
pathmax = 1024
) )
// Query to keep track of in-process query // Query to keep track of in-process query
@@ -87,11 +88,11 @@ func WithBatchSize(size uint32) Option {
func (q *Query) Next() ([]InodesEntry, error) { func (q *Query) Next() ([]InodesEntry, error) {
buf := make([]byte, int(unsafe.Sizeof(InodesEntry{}))*int(q.batch)) buf := make([]byte, int(unsafe.Sizeof(InodesEntry{}))*int(q.batch))
query := queryInodes{ query := queryInodes{
first: q.first, First: q.first,
last: q.last, Last: q.last,
entries: uintptr(unsafe.Pointer(&buf[0])), Entries_ptr: uint64(uintptr(unsafe.Pointer(&buf[0]))),
count: q.batch, Nr_entries: q.batch,
index: q.index, Index: q.index,
} }
n, err := scoutfsctl(q.fsfd.Fd(), IOCQUERYINODES, uintptr(unsafe.Pointer(&query))) n, err := scoutfsctl(q.fsfd.Fd(), IOCQUERYINODES, uintptr(unsafe.Pointer(&query)))
@@ -141,7 +142,7 @@ func StatMore(path string) (Stat, error) {
// FStatMore returns scoutfs specific metadata for file handle // FStatMore returns scoutfs specific metadata for file handle
func FStatMore(f *os.File) (Stat, error) { func FStatMore(f *os.File) (Stat, error) {
s := Stat{ValidBytes: uint64(unsafe.Sizeof(Stat{}))} s := Stat{Valid_bytes: uint64(unsafe.Sizeof(Stat{}))}
_, err := scoutfsctl(f.Fd(), IOCSTATMORE, uintptr(unsafe.Pointer(&s))) _, err := scoutfsctl(f.Fd(), IOCSTATMORE, uintptr(unsafe.Pointer(&s)))
if err != nil { if err != nil {
@@ -169,26 +170,34 @@ func FSetAttrMore(f *os.File, version, size, flags uint64, ctime time.Time) erro
nsec = int32(ctime.UnixNano()) nsec = int32(ctime.UnixNano())
} }
s := setattrMore{ s := setattrMore{
dataVersion: version, Data_version: version,
iSize: size, I_size: size,
flags: flags, Flags: flags,
ctimesec: uint64(ctime.Unix()), Ctime_sec: uint64(ctime.Unix()),
ctimensec: uint32(nsec), Ctime_nsec: uint32(nsec),
} }
_, err := scoutfsctl(f.Fd(), IOCSETATTRMORE, uintptr(unsafe.Pointer(&s))) _, err := scoutfsctl(f.Fd(), IOCSETATTRMORE, uintptr(unsafe.Pointer(&s)))
return err return err
} }
type inoPathResult struct {
DirIno uint64
DirPos uint64
PathSize uint16
_ [6]uint8
Path [pathmax]byte
}
// InoToPath converts an inode number to a path in the filesystem // InoToPath converts an inode number to a path in the filesystem
// An open file within scoutfs is supplied for ioctls // An open file within scoutfs is supplied for ioctls
// (usually just the base mount point directory) // (usually just the base mount point directory)
func InoToPath(dirfd *os.File, ino uint64) (string, error) { func InoToPath(dirfd *os.File, ino uint64) (string, error) {
var res InoPathResult var res inoPathResult
ip := InoPath{ ip := inoPath{
Ino: ino, Ino: ino,
ResultPtr: uint64(uintptr(unsafe.Pointer(&res))), Result_ptr: uint64(uintptr(unsafe.Pointer(&res))),
ResultSize: uint16(unsafe.Sizeof(res)), Result_bytes: uint16(unsafe.Sizeof(res)),
} }
_, err := scoutfsctl(dirfd.Fd(), IOCINOPATH, uintptr(unsafe.Pointer(&ip))) _, err := scoutfsctl(dirfd.Fd(), IOCINOPATH, uintptr(unsafe.Pointer(&ip)))
@@ -228,9 +237,9 @@ func ReleaseFile(path string, version uint64) error {
// FReleaseFile marks file offline and frees associated extents // FReleaseFile marks file offline and frees associated extents
func FReleaseFile(f *os.File, version uint64) error { func FReleaseFile(f *os.File, version uint64) error {
r := IocRelease{ r := iocRelease{
Count: math.MaxUint64, Count: math.MaxUint64,
DataVersion: version, Version: version,
} }
_, err := scoutfsctl(f.Fd(), IOCRELEASE, uintptr(unsafe.Pointer(&r))) _, err := scoutfsctl(f.Fd(), IOCRELEASE, uintptr(unsafe.Pointer(&r)))
@@ -250,11 +259,11 @@ func StageFile(path string, version, offset uint64, b []byte) error {
// FStageFile rehydrates offline file // FStageFile rehydrates offline file
func FStageFile(f *os.File, version, offset uint64, b []byte) error { func FStageFile(f *os.File, version, offset uint64, b []byte) error {
r := IocStage{ r := iocStage{
DataVersion: version, Data_version: version,
BufPtr: uint64(uintptr(unsafe.Pointer(&b[0]))), Buf_ptr: uint64(uintptr(unsafe.Pointer(&b[0]))),
Offset: offset, Offset: offset,
count: int32(len(b)), Count: int32(len(b)),
} }
_, err := scoutfsctl(f.Fd(), IOCSTAGE, uintptr(unsafe.Pointer(&r))) _, err := scoutfsctl(f.Fd(), IOCSTAGE, uintptr(unsafe.Pointer(&r)))
@@ -300,10 +309,10 @@ func WithWaitersCount(size uint16) WOption {
func (w *Waiters) Next() ([]DataWaitingEntry, error) { func (w *Waiters) Next() ([]DataWaitingEntry, error) {
buf := make([]byte, int(unsafe.Sizeof(DataWaitingEntry{}))*int(w.batch)) buf := make([]byte, int(unsafe.Sizeof(DataWaitingEntry{}))*int(w.batch))
dataWaiting := dataWaiting{ dataWaiting := dataWaiting{
afterIno: w.ino, After_ino: w.ino,
afterIblock: w.iblock, After_iblock: w.iblock,
entries: uintptr(unsafe.Pointer(&buf[0])), Ents_ptr: uint64(uintptr(unsafe.Pointer(&buf[0]))),
count: w.batch, Ents_nr: w.batch,
} }
n, err := scoutfsctl(w.fsfd.Fd(), IOCDATAWAITING, uintptr(unsafe.Pointer(&dataWaiting))) n, err := scoutfsctl(w.fsfd.Fd(), IOCDATAWAITING, uintptr(unsafe.Pointer(&dataWaiting)))
@@ -392,11 +401,11 @@ func (q *XattrQuery) Next() ([]uint64, error) {
buf := make([]byte, 8*int(q.batch)) buf := make([]byte, 8*int(q.batch))
name := []byte(q.key) name := []byte(q.key)
query := findXattrs{ query := findXattrs{
nextIno: q.next, Next_ino: q.next,
name: uintptr(unsafe.Pointer(&name[0])), Name_ptr: uint64(uintptr(unsafe.Pointer(&name[0]))),
inodesBuf: uintptr(unsafe.Pointer(&buf[0])), Inodes_ptr: uint64(uintptr(unsafe.Pointer(&buf[0]))),
nameSize: uint16(len(name)), Name_bytes: uint16(len(name)),
inodeCount: uint16(q.batch), Nr_inodes: uint16(q.batch),
} }
n, err := scoutfsctl(q.fsfd.Fd(), IOCFINDXATTRS, uintptr(unsafe.Pointer(&query))) n, err := scoutfsctl(q.fsfd.Fd(), IOCFINDXATTRS, uintptr(unsafe.Pointer(&query)))
@@ -427,27 +436,27 @@ func (q *XattrQuery) Next() ([]uint64, error) {
return inodes, nil return inodes, nil
} }
// ListXattrRaw holds info for iterating on xattrs // ListXattrHidden holds info for iterating on xattrs
type ListXattrRaw struct { type ListXattrHidden struct {
lxr *listXattrRaw lxr *listXattrHidden
f *os.File f *os.File
} }
// NewListXattrRaw will list all scoutfs xattrs (including hidden) for file // NewListXattrHidden will list all scoutfs xattrs (including hidden) for file
func NewListXattrRaw(f *os.File) *ListXattrRaw { func NewListXattrHidden(f *os.File) *ListXattrHidden {
return &ListXattrRaw{ return &ListXattrHidden{
f: f, f: f,
lxr: &listXattrRaw{}, lxr: &listXattrHidden{},
} }
} }
// Next gets next set of results, complete when string slice is nil // Next gets next set of results, complete when string slice is nil
func (l *ListXattrRaw) Next() ([]string, error) { func (l *ListXattrHidden) Next() ([]string, error) {
l.lxr.bufSize = 256 * 1024 l.lxr.Buf_bytes = 256 * 1024
buf := make([]byte, 256*1024) buf := make([]byte, 256*1024)
l.lxr.buf = uintptr(unsafe.Pointer(&buf[0])) l.lxr.Buf_ptr = uint64(uintptr(unsafe.Pointer(&buf[0])))
n, err := scoutfsctl(l.f.Fd(), IOCLISTXATTRRAW, uintptr(unsafe.Pointer(l.lxr))) n, err := scoutfsctl(l.f.Fd(), IOCLISTXATTRHIDDEN, uintptr(unsafe.Pointer(l.lxr)))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -1,346 +1,100 @@
// Copyright (c) 2018 Versity Software, Inc. // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// // cgo -godefs c_defs_linux.go
// Use of this source code is governed by a BSD-3-Clause license
// that can be found in the LICENSE file in the root of the source
// tree.
// The _ struct members are not necessary, but just there to be explicit
// in the matching up with the C struct alignment. The Go structs follow
// the same alignment rules, so should be compatible without these fields.
package scoutfs package scoutfs
const ( const IOCQUERYINODES = 0x80487301
// IOCQUERYINODES scoutfs ioctl const IOCINOPATH = 0x80287302
IOCQUERYINODES = 0x40487301 const IOCRELEASE = 0x40187303
// IOCINOPATH scoutfs ioctl const IOCSTAGE = 0x40207304
IOCINOPATH = 0x40287302 const IOCSTATMORE = 0x80307305
// IOCDATAVERSION scoutfs ioctl const IOCDATAWAITING = 0x80287307
IOCDATAVERSION = 0x40087304 const IOCSETATTRMORE = 0x40287308
// IOCRELEASE scoutfs ioctl const IOCLISTXATTRHIDDEN = 0x80187309
IOCRELEASE = 0x40187305 const IOCFINDXATTRS = 0x8020730a
// IOCSTAGE scoutfs ioctl
IOCSTAGE = 0x40207306
// IOCSTATMORE scoutfs ioctl
IOCSTATMORE = 0x40307307
// IOCDATAWAITING scoutfs ioctl
IOCDATAWAITING = 0x40287309
// IOCSETATTRMORE scoutfs ioctl
IOCSETATTRMORE = 0x4028730a
// IOCLISTXATTRRAW scoutfs ioctl
IOCLISTXATTRRAW = 0x4018730b
// IOCFINDXATTRS scoutfs ioctl
IOCFINDXATTRS = 0x4020730c
// QUERYINODESMETASEQ find inodes by metadata sequence const QUERYINODESMETASEQ = 0x0
QUERYINODESMETASEQ = '\u0000' const QUERYINODESDATASEQ = 0x1
// QUERYINODESDATASEQ find inodes by data sequence
QUERYINODESDATASEQ = '\u0001'
// DATAWAITOPREAD waiting operation read const DATAWAITOPREAD = 0x1
DATAWAITOPREAD = 1 << 0 const DATAWAITOPWRITE = 0x2
// DATAWAITOPWRITE waiting operation write const DATAWAITOPCHANGESIZE = 0x4
DATAWAITOPWRITE = 1 << 1
// DATAWAITOPCHANGESIZE waiting operation truncate
DATAWAITOPCHANGESIZE = 1 << 2
pathmax = 1024
)
/* pahole for scoutfs_ioctl_walk_inodes_entry
struct scoutfs_ioctl_walk_inodes_entry {
__u64 major; // 0 8
__u64 ino; // 8 8
__u32 minor; // 16 4
__u8 _pad[4]; // 20 4
// size: 24, cachelines: 1, members: 4
// last cacheline: 24 bytes
};
*/
// InodesEntry is scoutfs entry for inode iteration
type InodesEntry struct { type InodesEntry struct {
Major uint64 Major uint64
Ino uint64 Ino uint64
Minor uint32 Minor uint32
_ [4]uint8 X_pad [4]uint8
} }
/* pahole for scoutfs_ioctl_walk_inodes
struct scoutfs_ioctl_walk_inodes {
struct scoutfs_ioctl_walk_inodes_entry first; // 0 24
struct scoutfs_ioctl_walk_inodes_entry last; // 24 24
__u64 entries_ptr; // 48 8
__u32 nr_entries; // 56 4
__u8 index; // 60 1
__u8 _pad[11]; // 61 11
// --- cacheline 1 boundary (64 bytes) was 8 bytes ago ---
// size: 72, cachelines: 2, members: 6
// last cacheline: 8 bytes
};
*/
// queryInodes is scoutfs request structure for IOCQUERYINODES
type queryInodes struct { type queryInodes struct {
first InodesEntry First InodesEntry
last InodesEntry Last InodesEntry
entries uintptr Entries_ptr uint64
count uint32 Nr_entries uint32
index uint8 Index uint8
_ [11]uint8 X_pad [11]uint8
} }
type inoPath struct {
/* pahole for scoutfs_ioctl_ino_path Ino uint64
struct scoutfs_ioctl_ino_path { Dir_ino uint64
__u64 ino; // 0 8 Dir_pos uint64
__u64 dir_ino; // 8 8 Result_ptr uint64
__u64 dir_pos; // 16 8 Result_bytes uint16
__u64 result_ptr; // 24 8 X_pad [6]uint8
__u16 result_bytes; // 32 2
__u8 _pad[6]; // 34 6
// size: 40, cachelines: 1, members: 6
// last cacheline: 40 bytes
};
*/
// InoPath ioctl struct
type InoPath struct {
Ino uint64
DirIno uint64
DirPos uint64
ResultPtr uint64
ResultSize uint16
_ [6]uint8
} }
type iocRelease struct {
/* pahole for scoutfs_ioctl_ino_path_result Block uint64
struct scoutfs_ioctl_ino_path_result { Count uint64
__u64 dir_ino; // 0 8 Version uint64
__u64 dir_pos; // 8 8
__u16 path_bytes; // 16 2
__u8 _pad[6]; // 18 6
__u8 path[0]; // 24 0
// size: 24, cachelines: 1, members: 5
// last cacheline: 24 bytes
};
*/
// InoPathResult ioctl struct
type InoPathResult struct {
DirIno uint64
DirPos uint64
PathSize uint16
_ [6]uint8
Path [pathmax]byte
} }
type iocStage struct {
/* pahole for scoutfs_ioctl_release Data_version uint64
struct scoutfs_ioctl_release { Buf_ptr uint64
__u64 block; // 0 8 Offset uint64
__u64 count; // 8 8 Count int32
__u64 data_version; // 16 8 X_pad uint32
// size: 24, cachelines: 1, members: 3
// last cacheline: 24 bytes
};
*/
// IocRelease ioctl struct
type IocRelease struct {
Block uint64
Count uint64
DataVersion uint64
} }
/* pahole for scoutfs_ioctl_stage
struct scoutfs_ioctl_stage {
__u64 data_version; // 0 8
__u64 buf_ptr; // 8 8
__u64 offset; // 16 8
__s32 count; // 24 4
__u32 _pad; // 28 4
// size: 32, cachelines: 1, members: 5
// last cacheline: 32 bytes
};
*/
// IocStage ioctl struct
type IocStage struct {
DataVersion uint64
BufPtr uint64
Offset uint64
count int32
_ uint32
}
/* pahole for scoutfs_ioctl_stat_more
struct scoutfs_ioctl_stat_more {
__u64 valid_bytes; // 0 8
__u64 meta_seq; // 8 8
__u64 data_seq; // 16 8
__u64 data_version; // 24 8
__u64 online_blocks; // 32 8
__u64 offline_blocks; // 40 8
// size: 48, cachelines: 1, members: 6
// last cacheline: 48 bytes
};
*/
// Stat holds scoutfs specific per file metadata
type Stat struct { type Stat struct {
ValidBytes uint64 Valid_bytes uint64
MetaSeq uint64 Meta_seq uint64
DataSeq uint64 Data_seq uint64
DataVersion uint64 Data_version uint64
OnlineBlocks uint64 Online_blocks uint64
OfflineBlocks uint64 Offline_blocks uint64
} }
/* pahole for scoutfs_fid
struct scoutfs_fid {
__le64 ino; // 0 8
__le64 parent_ino; // 8 8
// size: 16, cachelines: 1, members: 2
// last cacheline: 16 bytes
};
*/
// FileID for file by ID operations
type FileID struct {
Ino uint64
ParentIno uint64
}
/* pahole for scoutfs_file_handle
struct scoutfs_file_handle {
unsigned int handle_bytes; // 0 4
int handle_type; // 4 4
struct scoutfs_fid fid; // 8 16
// size: 24, cachelines: 1, members: 3
// last cacheline: 24 bytes
};
*/
// FileHandle is the scoutfs specific file handle for open by handle operations
type FileHandle struct {
FidSize uint32
HandleType int32
FID FileID
}
/* pahole for scoutfs_ioctl_data_waiting_entry
struct scoutfs_ioctl_data_waiting_entry {
__u64 ino; // 0 8
__u64 iblock; // 8 8
__u8 op; // 16 1
__u8 _pad[7]; // 17 7
// size: 24, cachelines: 1, members: 4
// last cacheline: 24 bytes
};
*/
// DataWaitingEntry is an entry returned when a process is waiting on
// access of offline block
type DataWaitingEntry struct { type DataWaitingEntry struct {
Ino uint64 Ino uint64
Iblock uint64 Iblock uint64
Op uint8 Op uint8
_ [7]uint8 X_pad [7]uint8
} }
/* pahole for scoutfs_ioctl_data_waiting
struct scoutfs_ioctl_data_waiting {
__u64 flags; // 0 8
__u64 after_ino; // 8 8
__u64 after_iblock; // 16 8
__u64 ents_ptr; // 24 8
__u16 ents_nr; // 32 2
__u8 _pad[6]; // 34 6
// size: 40, cachelines: 1, members: 6
// last cacheline: 40 bytes
};
*/
type dataWaiting struct { type dataWaiting struct {
flags uint64 Flags uint64
afterIno uint64 After_ino uint64
afterIblock uint64 After_iblock uint64
entries uintptr Ents_ptr uint64
count uint16 Ents_nr uint16
_ [6]uint8 X_pad [6]uint8
} }
/* pahole for scoutfs_ioctl_setattr_more
struct scoutfs_ioctl_setattr_more {
__u64 data_version; // 0 8
__u64 i_size; // 8 8
__u64 flags; // 16 8
__u64 ctime_sec; // 24 8
__u32 ctime_nsec; // 32 4
__u8 _pad[4]; // 36 4
// size: 40, cachelines: 1, members: 6
// last cacheline: 40 bytes
};
*/
type setattrMore struct { type setattrMore struct {
dataVersion uint64 Data_version uint64
iSize uint64 I_size uint64
flags uint64 Flags uint64
ctimesec uint64 Ctime_sec uint64
ctimensec uint32 Ctime_nsec uint32
_ [4]uint8 X_pad [4]uint8
} }
type listXattrHidden struct {
/* pahole for scoutfs_ioctl_listxattr_raw Id_pos uint64
struct scoutfs_ioctl_listxattr_raw { Buf_ptr uint64
__u64 id_pos; // 0 8 Buf_bytes uint32
__u64 buf_ptr; // 8 8 Hash_pos uint32
__u32 buf_bytes; // 16 4
__u32 hash_pos; // 20 4
// size: 24, cachelines: 1, members: 4
// last cacheline: 24 bytes
};
*/
type listXattrRaw struct {
idPos uint64
buf uintptr
bufSize uint32
hashPos uint32
} }
/* pahole for scoutfs_ioctl_find_xattrs
struct scoutfs_ioctl_find_xattrs {
__u64 next_ino; // 0 8
__u64 name_ptr; // 8 8
__u64 inodes_ptr; // 16 8
__u16 name_bytes; // 24 2
__u16 nr_inodes; // 26 2
__u8 _pad[4]; // 28 4
// size: 32, cachelines: 1, members: 6
// last cacheline: 32 bytes
};
*/
type findXattrs struct { type findXattrs struct {
nextIno uint64 Next_ino uint64
name uintptr Name_ptr uint64
inodesBuf uintptr Inodes_ptr uint64
nameSize uint16 Name_bytes uint16
inodeCount uint16 Nr_inodes uint16
_ [4]uint8 X_pad [4]uint8
} }

View File

@@ -13,20 +13,31 @@ const (
FILEID_SCOUTFS = 0x81 FILEID_SCOUTFS = 0x81
) )
type fileID struct {
Ino uint64
ParentIno uint64
}
type fileHandle struct {
FidSize uint32
HandleType int32
FID fileID
}
// OpenByHandle is similar to OpenByID, but returns just the file descriptor // OpenByHandle is similar to OpenByID, but returns just the file descriptor
// and does not have the added overhead of getting the filename // and does not have the added overhead of getting the filename
// An open file within scoutfs is supplied for ioctls // An open file within scoutfs is supplied for ioctls
// (usually just the base mount point directory) // (usually just the base mount point directory)
func OpenByHandle(dirfd *os.File, ino uint64, flags int) (uintptr, error) { func OpenByHandle(dirfd *os.File, ino uint64, flags int) (uintptr, error) {
h := &FileHandle{ h := &fileHandle{
FidSize: uint32(unsafe.Sizeof(FileID{})), FidSize: uint32(unsafe.Sizeof(fileID{})),
HandleType: FILEID_SCOUTFS, HandleType: FILEID_SCOUTFS,
FID: FileID{Ino: ino}, FID: fileID{Ino: ino},
} }
return openbyhandleat(dirfd.Fd(), h, flags) return openbyhandleat(dirfd.Fd(), h, flags)
} }
func openbyhandleat(dirfd uintptr, handle *FileHandle, flags int) (uintptr, error) { func openbyhandleat(dirfd uintptr, handle *fileHandle, flags int) (uintptr, error) {
fd, _, e1 := syscall.Syscall6(SYS_OPENBYHANDLEAT, dirfd, uintptr(unsafe.Pointer(handle)), uintptr(flags), 0, 0, 0) fd, _, e1 := syscall.Syscall6(SYS_OPENBYHANDLEAT, dirfd, uintptr(unsafe.Pointer(handle)), uintptr(flags), 0, 0, 0)
var err error var err error
if e1 != 0 { if e1 != 0 {