small refactor*
This commit is contained in:
parent
b6b541e050
commit
24a4d30275
232 changed files with 2164 additions and 1906 deletions
27
server/pkg/ctxbilly/change.go
Normal file
27
server/pkg/ctxbilly/change.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package ctxbilly
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Change abstract the FileInfo change related operations in a storage-agnostic
|
||||
// interface as an extension to the Basic interface
|
||||
type Change interface {
|
||||
// Chmod changes the mode of the named file to mode. If the file is a
|
||||
// symbolic link, it changes the mode of the link's target.
|
||||
Chmod(ctx context.Context, name string, mode os.FileMode) error
|
||||
// Lchown changes the numeric uid and gid of the named file. If the file is
|
||||
// a symbolic link, it changes the uid and gid of the link itself.
|
||||
Lchown(ctx context.Context, name string, uid, gid int) error
|
||||
// Chown changes the numeric uid and gid of the named file. If the file is a
|
||||
// symbolic link, it changes the uid and gid of the link's target.
|
||||
Chown(ctx context.Context, name string, uid, gid int) error
|
||||
// Chtimes changes the access and modification times of the named file,
|
||||
// similar to the Unix utime() or utimes() functions.
|
||||
//
|
||||
// The underlying filesystem may truncate or round the values to a less
|
||||
// precise time unit.
|
||||
Chtimes(ctx context.Context, name string, atime time.Time, mtime time.Time) error
|
||||
}
|
97
server/pkg/ctxbilly/fs.go
Normal file
97
server/pkg/ctxbilly/fs.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
package ctxbilly
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/royalcat/ctxio"
|
||||
)
|
||||
|
||||
type Filesystem interface {
|
||||
// Create creates the named file with mode 0666 (before umask), truncating
|
||||
// it if it already exists. If successful, methods on the returned File can
|
||||
// be used for I/O; the associated file descriptor has mode O_RDWR.
|
||||
Create(ctx context.Context, filename string) (File, error)
|
||||
// OpenFile is the generalized open call; most users will use Open or Create
|
||||
// instead. It opens the named file with specified flag (O_RDONLY etc.) and
|
||||
// perm, (0666 etc.) if applicable. If successful, methods on the returned
|
||||
// File can be used for I/O.
|
||||
OpenFile(ctx context.Context, filename string, flag int, perm os.FileMode) (File, error)
|
||||
// Stat returns a FileInfo describing the named file.
|
||||
Stat(ctx context.Context, filename string) (os.FileInfo, error)
|
||||
// Rename renames (moves) oldpath to newpath. If newpath already exists and
|
||||
// is not a directory, Rename replaces it. OS-specific restrictions may
|
||||
// apply when oldpath and newpath are in different directories.
|
||||
Rename(ctx context.Context, oldpath, newpath string) error
|
||||
// Remove removes the named file or directory.
|
||||
Remove(ctx context.Context, filename string) error
|
||||
// Join joins any number of path elements into a single path, adding a
|
||||
// Separator if necessary. Join calls filepath.Clean on the result; in
|
||||
// particular, all empty strings are ignored. On Windows, the result is a
|
||||
// UNC path if and only if the first path element is a UNC path.
|
||||
Join(elem ...string) string
|
||||
|
||||
// ReadDir reads the directory named by d(irname and returns a list of
|
||||
// directory entries sorted by filename.
|
||||
ReadDir(ctx context.Context, path string) ([]os.FileInfo, error)
|
||||
// MkdirAll creates a directory named path, along with any necessary
|
||||
// parents, and returns nil, or else returns an error. The permission bits
|
||||
// perm are used for all directories that MkdirAll creates. If path is/
|
||||
// already a directory, MkdirAll does nothing and returns nil.
|
||||
MkdirAll(ctx context.Context, filename string, perm os.FileMode) error
|
||||
|
||||
// Lstat returns a FileInfo describing the named file. If the file is a
|
||||
// symbolic link, the returned FileInfo describes the symbolic link. Lstat
|
||||
// makes no attempt to follow the link.
|
||||
Lstat(ctx context.Context, filename string) (os.FileInfo, error)
|
||||
// Symlink creates a symbolic-link from link to target. target may be an
|
||||
// absolute or relative path, and need not refer to an existing node.
|
||||
// Parent directories of link are created as necessary.
|
||||
Symlink(ctx context.Context, target, link string) error
|
||||
// Readlink returns the target path of link.
|
||||
Readlink(ctx context.Context, link string) (string, error)
|
||||
|
||||
// // Chroot returns a new filesystem from the same type where the new root is
|
||||
// // the given path. Files outside of the designated directory tree cannot be
|
||||
// // accessed.
|
||||
// Chroot(path string) (Filesystem, error)
|
||||
// // Root returns the root path of the filesystem.
|
||||
// Root() string
|
||||
}
|
||||
|
||||
type TempFileFS interface {
|
||||
// TempFile creates a new temporary file in the directory dir with a name
|
||||
// beginning with prefix, opens the file for reading and writing, and
|
||||
// returns the resulting *os.File. If dir is the empty string, TempFile
|
||||
// uses the default directory for temporary files (see os.TempDir).
|
||||
// Multiple programs calling TempFile simultaneously will not choose the
|
||||
// same file. The caller can use f.Name() to find the pathname of the file.
|
||||
// It is the caller's responsibility to remove the file when no longer
|
||||
// needed.
|
||||
TempFile(ctx context.Context, dir, prefix string) (File, error)
|
||||
}
|
||||
|
||||
type File interface {
|
||||
// Name returns the name of the file as presented to Open.
|
||||
Name() string
|
||||
ctxio.Writer
|
||||
ctxio.WriterAt
|
||||
ctxio.Reader
|
||||
ctxio.ReaderAt
|
||||
io.Seeker
|
||||
ctxio.Closer
|
||||
}
|
||||
|
||||
type LockFile interface {
|
||||
// Lock locks the file like e.g. flock. It protects against access from
|
||||
// other processes.
|
||||
Lock() error
|
||||
// Unlock unlocks the file.
|
||||
Unlock() error
|
||||
}
|
||||
|
||||
type TruncateFile interface {
|
||||
// Truncate the file.
|
||||
Truncate(ctx context.Context, size int64) error
|
||||
}
|
175
server/pkg/ctxbilly/mem.go
Normal file
175
server/pkg/ctxbilly/mem.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
package ctxbilly
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/fs"
|
||||
|
||||
"github.com/go-git/go-billy/v5"
|
||||
)
|
||||
|
||||
func WrapFileSystem(bf billy.Filesystem) Filesystem {
|
||||
return &wrapFS{
|
||||
Filesystem: bf,
|
||||
}
|
||||
}
|
||||
|
||||
type wrapFS struct {
|
||||
billy.Filesystem
|
||||
}
|
||||
|
||||
var _ Filesystem = (*wrapFS)(nil)
|
||||
|
||||
// Create implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Create of MemFS.Filesystem.
|
||||
func (m *wrapFS) Create(ctx context.Context, filename string) (File, error) {
|
||||
bf, err := m.Filesystem.Create(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &wrapFile{bf}, nil
|
||||
}
|
||||
|
||||
// Lstat implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Lstat of MemFS.Filesystem.
|
||||
func (m *wrapFS) Lstat(ctx context.Context, filename string) (fs.FileInfo, error) {
|
||||
return m.Filesystem.Lstat(filename)
|
||||
}
|
||||
|
||||
// MkdirAll implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).MkdirAll of MemFS.Filesystem.
|
||||
func (m *wrapFS) MkdirAll(ctx context.Context, filename string, perm fs.FileMode) error {
|
||||
return m.Filesystem.MkdirAll(filename, perm)
|
||||
}
|
||||
|
||||
// Open implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Open of MemFS.Filesystem.
|
||||
func (m *wrapFS) Open(ctx context.Context, filename string) (File, error) {
|
||||
bf, err := m.Filesystem.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return WrapFile(bf), nil
|
||||
}
|
||||
|
||||
// OpenFile implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).OpenFile of MemFS.Filesystem.
|
||||
func (m *wrapFS) OpenFile(ctx context.Context, filename string, flag int, perm fs.FileMode) (File, error) {
|
||||
bf, err := m.Filesystem.OpenFile(filename, flag, perm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return WrapFile(bf), nil
|
||||
}
|
||||
|
||||
// ReadDir implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).ReadDir of MemFS.Filesystem.
|
||||
func (m *wrapFS) ReadDir(ctx context.Context, path string) ([]fs.FileInfo, error) {
|
||||
return m.Filesystem.ReadDir(path)
|
||||
}
|
||||
|
||||
// Readlink implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Readlink of MemFS.Filesystem.
|
||||
func (m *wrapFS) Readlink(ctx context.Context, link string) (string, error) {
|
||||
return m.Filesystem.Readlink(link)
|
||||
}
|
||||
|
||||
// Remove implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Remove of MemFS.Filesystem.
|
||||
func (m *wrapFS) Remove(ctx context.Context, filename string) error {
|
||||
return m.Filesystem.Remove(filename)
|
||||
}
|
||||
|
||||
// Rename implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Rename of MemFS.Filesystem.
|
||||
func (m *wrapFS) Rename(ctx context.Context, oldpath string, newpath string) error {
|
||||
return m.Filesystem.Rename(oldpath, newpath)
|
||||
}
|
||||
|
||||
// Stat implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Stat of MemFS.Filesystem.
|
||||
func (m *wrapFS) Stat(ctx context.Context, filename string) (fs.FileInfo, error) {
|
||||
return m.Filesystem.Stat(filename)
|
||||
}
|
||||
|
||||
// Symlink implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).Symlink of MemFS.Filesystem.
|
||||
func (m *wrapFS) Symlink(ctx context.Context, target string, link string) error {
|
||||
return m.Filesystem.Symlink(target, link)
|
||||
}
|
||||
|
||||
// TempFile implements Filesystem.
|
||||
// Subtle: this method shadows the method (Filesystem).TempFile of MemFS.Filesystem.
|
||||
func (m *wrapFS) TempFile(ctx context.Context, dir string, prefix string) (File, error) {
|
||||
file, err := m.Filesystem.TempFile(dir, prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return WrapFile(file), nil
|
||||
}
|
||||
|
||||
func WrapFile(bf billy.File) File {
|
||||
return &wrapFile{File: bf}
|
||||
}
|
||||
|
||||
type wrapFile struct {
|
||||
billy.File
|
||||
}
|
||||
|
||||
var _ File = (*wrapFile)(nil)
|
||||
|
||||
// Close implements File.
|
||||
// Subtle: this method shadows the method (File).Close of MemFile.File.
|
||||
func (m *wrapFile) Close(ctx context.Context) error {
|
||||
return m.File.Close()
|
||||
}
|
||||
|
||||
// Lock implements File.
|
||||
// Subtle: this method shadows the method (File).Lock of MemFile.File.
|
||||
func (m *wrapFile) Lock() error {
|
||||
return m.File.Lock()
|
||||
}
|
||||
|
||||
// Name implements File.
|
||||
// Subtle: this method shadows the method (File).Name of MemFile.File.
|
||||
func (m *wrapFile) Name() string {
|
||||
return m.File.Name()
|
||||
}
|
||||
|
||||
// Truncate implements File.
|
||||
// Subtle: this method shadows the method (File).Truncate of memFile.File.
|
||||
func (m *wrapFile) Truncate(ctx context.Context, size int64) error {
|
||||
return m.File.Truncate(size)
|
||||
}
|
||||
|
||||
// Read implements File.
|
||||
// Subtle: this method shadows the method (File).Read of MemFile.File.
|
||||
func (m *wrapFile) Read(ctx context.Context, p []byte) (n int, err error) {
|
||||
return m.File.Read(p)
|
||||
}
|
||||
|
||||
// ReadAt implements File.
|
||||
// Subtle: this method shadows the method (File).ReadAt of MemFile.File.
|
||||
func (m *wrapFile) ReadAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
||||
return m.File.ReadAt(p, off)
|
||||
}
|
||||
|
||||
// Unlock implements File.
|
||||
// Subtle: this method shadows the method (File).Unlock of MemFile.File.
|
||||
func (m *wrapFile) Unlock() error {
|
||||
return m.File.Unlock()
|
||||
}
|
||||
|
||||
// Write implements File.
|
||||
// Subtle: this method shadows the method (File).Write of MemFile.File.
|
||||
func (m *wrapFile) Write(ctx context.Context, p []byte) (n int, err error) {
|
||||
return m.File.Write(p)
|
||||
}
|
||||
|
||||
// WriteAt implements File.
|
||||
func (m *wrapFile) WriteAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
||||
_, err = m.File.Seek(off, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return m.File.Write(p)
|
||||
}
|
355
server/pkg/ctxbilly/uring.go
Normal file
355
server/pkg/ctxbilly/uring.go
Normal file
|
@ -0,0 +1,355 @@
|
|||
package ctxbilly
|
||||
|
||||
// import (
|
||||
// "context"
|
||||
// "errors"
|
||||
// "fmt"
|
||||
// "os"
|
||||
// "path/filepath"
|
||||
// "strings"
|
||||
|
||||
// securejoin "github.com/cyphar/filepath-securejoin"
|
||||
// "github.com/iceber/iouring-go"
|
||||
// )
|
||||
|
||||
// func NewURingFS() (*UringFS, error) {
|
||||
// ur, err := iouring.New(64, iouring.WithAsync())
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// return &UringFS{
|
||||
// ur: ur,
|
||||
// }, nil
|
||||
// }
|
||||
|
||||
// var _ Filesystem = (*UringFS)(nil)
|
||||
|
||||
// const (
|
||||
// defaultDirectoryMode = 0o755
|
||||
// defaultCreateMode = 0o666
|
||||
// )
|
||||
|
||||
// // UringFS is a fs implementation based on the OS filesystem which is bound to
|
||||
// // a base dir.
|
||||
// // Prefer this fs implementation over ChrootOS.
|
||||
// //
|
||||
// // Behaviours of note:
|
||||
// // 1. Read and write operations can only be directed to files which descends
|
||||
// // from the base dir.
|
||||
// // 2. Symlinks don't have their targets modified, and therefore can point
|
||||
// // to locations outside the base dir or to non-existent paths.
|
||||
// // 3. Readlink and Lstat ensures that the link file is located within the base
|
||||
// // dir, evaluating any symlinks that file or base dir may contain.
|
||||
// type UringFS struct {
|
||||
// ur *iouring.IOURing
|
||||
// baseDir string
|
||||
// }
|
||||
|
||||
// func newBoundOS(d string) *UringFS {
|
||||
// return &UringFS{baseDir: d}
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Create(ctx context.Context, filename string) (File, error) {
|
||||
// return fs.OpenFile(ctx, filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) OpenFile(ctx context.Context, filename string, flag int, perm os.FileMode) (File, error) {
|
||||
// fn, err := fs.abs(filename)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// f, err := os.OpenFile(fn, flag, perm)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// return newFile(fs.ur, f)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) ReadDir(ctx context.Context, path string) ([]os.FileInfo, error) {
|
||||
// dir, err := fs.abs(path)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// entries, err := os.ReadDir(dir)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// infos := make([]os.FileInfo, 0, len(entries))
|
||||
// for _, v := range entries {
|
||||
// info, err := v.Info()
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// infos = append(infos, info)
|
||||
// }
|
||||
|
||||
// return infos, nil
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Rename(ctx context.Context, from, to string) error {
|
||||
// f, err := fs.abs(from)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// t, err := fs.abs(to)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// // MkdirAll for target name.
|
||||
// if err := fs.createDir(t); err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// return os.Rename(f, t)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) MkdirAll(ctx context.Context, path string, perm os.FileMode) error {
|
||||
// dir, err := fs.abs(path)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return os.MkdirAll(dir, perm)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Stat(ctx context.Context, filename string) (os.FileInfo, error) {
|
||||
// filename, err := fs.abs(filename)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return os.Stat(filename)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Remove(ctx context.Context, filename string) error {
|
||||
// fn, err := fs.abs(filename)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return os.Remove(fn)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Join(elem ...string) string {
|
||||
// return filepath.Join(elem...)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) RemoveAll(path string) error {
|
||||
// dir, err := fs.abs(path)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return os.RemoveAll(dir)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Symlink(ctx context.Context, target, link string) error {
|
||||
// ln, err := fs.abs(link)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// // MkdirAll for containing dir.
|
||||
// if err := fs.createDir(ln); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return os.Symlink(target, ln)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Lstat(ctx context.Context, filename string) (os.FileInfo, error) {
|
||||
// filename = filepath.Clean(filename)
|
||||
// if !filepath.IsAbs(filename) {
|
||||
// filename = filepath.Join(fs.baseDir, filename)
|
||||
// }
|
||||
// if ok, err := fs.insideBaseDirEval(filename); !ok {
|
||||
// return nil, err
|
||||
// }
|
||||
// return os.Lstat(filename)
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) Readlink(ctx context.Context, link string) (string, error) {
|
||||
// if !filepath.IsAbs(link) {
|
||||
// link = filepath.Clean(filepath.Join(fs.baseDir, link))
|
||||
// }
|
||||
// if ok, err := fs.insideBaseDirEval(link); !ok {
|
||||
// return "", err
|
||||
// }
|
||||
// return os.Readlink(link)
|
||||
// }
|
||||
|
||||
// // Chroot returns a new OS filesystem, with the base dir set to the
|
||||
// // result of joining the provided path with the underlying base dir.
|
||||
// // func (fs *UringFS) Chroot(path string) (Filesystem, error) {
|
||||
// // joined, err := securejoin.SecureJoin(fs.baseDir, path)
|
||||
// // if err != nil {
|
||||
// // return nil, err
|
||||
// // }
|
||||
// // return newBoundOS(joined), nil
|
||||
// // }
|
||||
|
||||
// // Root returns the current base dir of the billy.Filesystem.
|
||||
// // This is required in order for this implementation to be a drop-in
|
||||
// // replacement for other upstream implementations (e.g. memory and osfs).
|
||||
// func (fs *UringFS) Root() string {
|
||||
// return fs.baseDir
|
||||
// }
|
||||
|
||||
// func (fs *UringFS) createDir(fullpath string) error {
|
||||
// dir := filepath.Dir(fullpath)
|
||||
// if dir != "." {
|
||||
// if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// // abs transforms filename to an absolute path, taking into account the base dir.
|
||||
// // Relative paths won't be allowed to ascend the base dir, so `../file` will become
|
||||
// // `/working-dir/file`.
|
||||
// //
|
||||
// // Note that if filename is a symlink, the returned address will be the target of the
|
||||
// // symlink.
|
||||
// func (fs *UringFS) abs(filename string) (string, error) {
|
||||
// if filename == fs.baseDir {
|
||||
// filename = string(filepath.Separator)
|
||||
// }
|
||||
|
||||
// path, err := securejoin.SecureJoin(fs.baseDir, filename)
|
||||
// if err != nil {
|
||||
// return "", nil
|
||||
// }
|
||||
|
||||
// return path, nil
|
||||
// }
|
||||
|
||||
// // insideBaseDirEval checks whether filename is contained within
|
||||
// // a dir that is within the fs.baseDir, by first evaluating any symlinks
|
||||
// // that either filename or fs.baseDir may contain.
|
||||
// func (fs *UringFS) insideBaseDirEval(filename string) (bool, error) {
|
||||
// dir, err := filepath.EvalSymlinks(filepath.Dir(filename))
|
||||
// if dir == "" || os.IsNotExist(err) {
|
||||
// dir = filepath.Dir(filename)
|
||||
// }
|
||||
// wd, err := filepath.EvalSymlinks(fs.baseDir)
|
||||
// if wd == "" || os.IsNotExist(err) {
|
||||
// wd = fs.baseDir
|
||||
// }
|
||||
// if filename != wd && dir != wd && !strings.HasPrefix(dir, wd+string(filepath.Separator)) {
|
||||
// return false, fmt.Errorf("path outside base dir")
|
||||
// }
|
||||
// return true, nil
|
||||
// }
|
||||
|
||||
// func newFile(fsur *iouring.IOURing, f *os.File) (*URingFile, error) {
|
||||
// ur, err := iouring.New(64, iouring.WithAttachWQ(fsur))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// return &URingFile{
|
||||
// ur: ur,
|
||||
// f: f,
|
||||
// }, nil
|
||||
// }
|
||||
|
||||
// type URingFile struct {
|
||||
// ur *iouring.IOURing
|
||||
// f *os.File
|
||||
// }
|
||||
|
||||
// // Close implements File.
|
||||
// func (o *URingFile) Close(ctx context.Context) error {
|
||||
// return errors.Join(o.ur.UnregisterFile(o.f), o.Close(ctx))
|
||||
// }
|
||||
|
||||
// // Name implements File.
|
||||
// func (o *URingFile) Name() string {
|
||||
// return o.f.Name()
|
||||
// }
|
||||
|
||||
// // Read implements File.
|
||||
// func (o *URingFile) Read(ctx context.Context, p []byte) (n int, err error) {
|
||||
// req, err := o.ur.Read(o.f, p, nil)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// defer req.Cancel()
|
||||
|
||||
// select {
|
||||
// case <-req.Done():
|
||||
// return req.GetRes()
|
||||
// case <-ctx.Done():
|
||||
// req.Cancel()
|
||||
// <-req.Done()
|
||||
// return req.GetRes()
|
||||
// }
|
||||
// }
|
||||
|
||||
// // ReadAt implements File.
|
||||
// func (o *URingFile) ReadAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
||||
// req, err := o.ur.Pread(o.f, p, uint64(off), nil)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// defer req.Cancel()
|
||||
|
||||
// select {
|
||||
// case <-req.Done():
|
||||
// return req.GetRes()
|
||||
// case <-ctx.Done():
|
||||
// req.Cancel()
|
||||
// <-req.Done()
|
||||
// return req.GetRes()
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Write implements File.
|
||||
// func (o *URingFile) Write(ctx context.Context, p []byte) (n int, err error) {
|
||||
// req, err := o.ur.Write(o.f, p, nil)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// defer req.Cancel()
|
||||
|
||||
// select {
|
||||
// case <-req.Done():
|
||||
// return req.GetRes()
|
||||
// case <-ctx.Done():
|
||||
// req.Cancel()
|
||||
// <-req.Done()
|
||||
// return req.GetRes()
|
||||
// }
|
||||
// }
|
||||
|
||||
// // WriteAt implements File.
|
||||
// func (o *URingFile) WriteAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
||||
// req, err := o.ur.Pwrite(o.f, p, uint64(off), nil)
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
// defer req.Cancel()
|
||||
|
||||
// select {
|
||||
// case <-req.Done():
|
||||
// return req.GetRes()
|
||||
// case <-ctx.Done():
|
||||
// req.Cancel()
|
||||
// <-req.Done()
|
||||
// return req.GetRes()
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Seek implements File.
|
||||
// func (o *URingFile) Seek(offset int64, whence int) (int64, error) {
|
||||
// return o.f.Seek(offset, whence)
|
||||
// }
|
||||
|
||||
// // Truncate implements File.
|
||||
// func (o *URingFile) Truncate(ctx context.Context, size int64) error {
|
||||
// return o.f.Truncate(size)
|
||||
// }
|
||||
|
||||
// var _ File = (*URingFile)(nil)
|
Loading…
Add table
Add a link
Reference in a new issue