github.com/pachyderm/pachyderm@v1.13.4/src/server/pfs/fuse/loopback_linux.go (about)

     1  package fuse
     2  
     3  import (
     4  	"context"
     5  	"syscall"
     6  
     7  	"github.com/hanwen/go-fuse/v2/fs"
     8  	"golang.org/x/sys/unix"
     9  )
    10  
    11  func (n *loopbackNode) renameExchange(name string, newparent *loopbackNode, newName string) syscall.Errno {
    12  	fd1, err := syscall.Open(n.path(), syscall.O_DIRECTORY, 0)
    13  	if err != nil {
    14  		return fs.ToErrno(err)
    15  	}
    16  	defer syscall.Close(fd1)
    17  	fd2, err := syscall.Open(newparent.path(), syscall.O_DIRECTORY, 0)
    18  	defer syscall.Close(fd2)
    19  	if err != nil {
    20  		return fs.ToErrno(err)
    21  	}
    22  
    23  	var st syscall.Stat_t
    24  	if err := syscall.Fstat(fd1, &st); err != nil {
    25  		return fs.ToErrno(err)
    26  	}
    27  
    28  	// Double check that nodes didn't change from under us.
    29  	inode := &n.Inode
    30  	if inode.Root() != inode && inode.StableAttr().Ino != n.root().idFromStat(&st).Ino {
    31  		return syscall.EBUSY
    32  	}
    33  	if err := syscall.Fstat(fd2, &st); err != nil {
    34  		return fs.ToErrno(err)
    35  	}
    36  
    37  	newinode := &newparent.Inode
    38  	if newinode.Root() != newinode && newinode.StableAttr().Ino != n.root().idFromStat(&st).Ino {
    39  		return syscall.EBUSY
    40  	}
    41  
    42  	return fs.ToErrno(unix.Renameat2(fd1, name, fd2, newName, unix.RENAME_EXCHANGE))
    43  }
    44  
    45  func (n *loopbackNode) CopyFileRange(ctx context.Context, fhIn fs.FileHandle,
    46  	offIn uint64, out *fs.Inode, fhOut fs.FileHandle, offOut uint64,
    47  	len uint64, flags uint64) (uint32, syscall.Errno) {
    48  	lfIn, ok := fhIn.(*loopbackFile)
    49  	if !ok {
    50  		return 0, syscall.ENOTSUP
    51  	}
    52  	lfOut, ok := fhOut.(*loopbackFile)
    53  	if !ok {
    54  		return 0, syscall.ENOTSUP
    55  	}
    56  
    57  	signedOffIn := int64(offIn)
    58  	signedOffOut := int64(offOut)
    59  	count, err := unix.CopyFileRange(lfIn.fd, &signedOffIn, lfOut.fd, &signedOffOut, int(len), int(flags))
    60  	return uint32(count), fs.ToErrno(err)
    61  }