Initial commit
Proof-of-concept implementation. Bugs will occur.
This commit is contained in:
80
vendor/github.com/hanwen/go-fuse/v2/fs/loopback_freebsd.go
generated
vendored
Normal file
80
vendor/github.com/hanwen/go-fuse/v2/fs/loopback_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2024 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"syscall"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/internal/xattr"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const unix_UTIME_OMIT = unix.UTIME_OMIT
|
||||
|
||||
// FreeBSD has added copy_file_range(2) since FreeBSD 12. However,
|
||||
// golang.org/x/sys/unix hasn't add corresponding syscall constant or
|
||||
// wrap function. Here we define the syscall constant until sys/unix
|
||||
// provides.
|
||||
const sys_COPY_FILE_RANGE = 569
|
||||
|
||||
// TODO: replace the manual syscall when sys/unix provides CopyFileRange
|
||||
// for FreeBSD
|
||||
func doCopyFileRange(fdIn int, offIn int64, fdOut int, offOut int64,
|
||||
len int, flags int) (uint32, syscall.Errno) {
|
||||
count, _, errno := unix.Syscall6(sys_COPY_FILE_RANGE,
|
||||
uintptr(fdIn), uintptr(offIn), uintptr(fdOut), uintptr(offOut),
|
||||
uintptr(len), uintptr(flags),
|
||||
)
|
||||
return uint32(count), errno
|
||||
}
|
||||
|
||||
func intDev(dev uint32) uint64 {
|
||||
return uint64(dev)
|
||||
}
|
||||
|
||||
// Since FUSE on FreeBSD expect Linux flavor data format of
|
||||
// listxattr, we should reconstruct it with data returned by
|
||||
// FreeBSD's syscall. And here we have added a "user." prefix
|
||||
// to put them under "user" namespace, which is readable and
|
||||
// writable for normal user, for a userspace implemented FS.
|
||||
func rebuildAttrBuf(attrList [][]byte) []byte {
|
||||
ret := make([]byte, 0)
|
||||
for _, attrName := range attrList {
|
||||
nsAttrName := append([]byte("user."), attrName...)
|
||||
ret = append(ret, nsAttrName...)
|
||||
ret = append(ret, 0x0)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
var _ = (NodeListxattrer)((*LoopbackNode)(nil))
|
||||
|
||||
func (n *LoopbackNode) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errno) {
|
||||
// In order to simulate same data format as Linux does,
|
||||
// and the size of returned buf is required to match, we must
|
||||
// call unix.Llistxattr twice.
|
||||
sz, err := unix.Llistxattr(n.path(), nil)
|
||||
if err != nil {
|
||||
return uint32(sz), ToErrno(err)
|
||||
}
|
||||
rawBuf := make([]byte, sz)
|
||||
sz, err = unix.Llistxattr(n.path(), rawBuf)
|
||||
if err != nil {
|
||||
return uint32(sz), ToErrno(err)
|
||||
}
|
||||
attrList := xattr.ParseAttrNames(rawBuf)
|
||||
rebuiltBuf := rebuildAttrBuf(attrList)
|
||||
sz = len(rebuiltBuf)
|
||||
if len(dest) != 0 {
|
||||
// When len(dest) is 0, which means that caller wants to get
|
||||
// the size. If len(dest) is less than len(rebuiltBuf), but greater
|
||||
// than 0 dest will be also filled with data from rebuiltBuf,
|
||||
// but truncated to len(dest). copy() function will do the same.
|
||||
// And this behaviour is same as FreeBSD's syscall extattr_list_file(2).
|
||||
sz = copy(dest, rebuiltBuf)
|
||||
}
|
||||
return uint32(sz), ToErrno(err)
|
||||
}
|
||||
Reference in New Issue
Block a user