1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
13 type filehandle struct {
19 unreaddirs []os.FileInfo
22 func (f *filehandle) Read(p []byte) (n int, err error) {
24 return 0, ErrWriteOnlyMode
27 defer f.inode.RUnlock()
28 n, f.ptr, err = f.inode.Read(p, f.ptr)
32 func (f *filehandle) Seek(off int64, whence int) (pos int64, err error) {
33 size := f.inode.Size()
44 return f.ptr.off, ErrNegativeOffset
46 if ptr.off != f.ptr.off {
48 // force filenode to recompute f.ptr fields on next
55 func (f *filehandle) Truncate(size int64) error {
56 return f.inode.Truncate(size)
59 func (f *filehandle) Write(p []byte) (n int, err error) {
61 return 0, ErrReadOnlyFile
64 defer f.inode.Unlock()
65 if fn, ok := f.inode.(*filenode); ok && f.append {
67 off: fn.fileinfo.size,
68 segmentIdx: len(fn.segments),
70 repacked: fn.repacked,
73 n, f.ptr, err = f.inode.Write(p, f.ptr)
77 // dirEntry implements fs.DirEntry, see (*filehandle)ReadDir().
78 type dirEntry struct {
82 func (ent dirEntry) Type() fs.FileMode {
83 return ent.Mode().Type()
85 func (ent dirEntry) Info() (fs.FileInfo, error) {
89 // ReadDir implements fs.ReadDirFile.
90 func (f *filehandle) ReadDir(count int) ([]fs.DirEntry, error) {
91 fis, err := f.Readdir(count)
95 ents := make([]fs.DirEntry, len(fis))
96 for i, fi := range fis {
97 ents[i] = dirEntry{fi}
102 func (f *filehandle) Readdir(count int) ([]os.FileInfo, error) {
103 if !f.inode.IsDir() {
104 return nil, ErrInvalidOperation
107 return f.inode.Readdir()
109 if f.unreaddirs == nil {
111 f.unreaddirs, err = f.inode.Readdir()
116 if len(f.unreaddirs) == 0 {
119 if count > len(f.unreaddirs) {
120 count = len(f.unreaddirs)
122 ret := f.unreaddirs[:count]
123 f.unreaddirs = f.unreaddirs[count:]
127 func (f *filehandle) Stat() (os.FileInfo, error) {
128 return f.inode.FileInfo(), nil
131 func (f *filehandle) Close() error {
135 func (f *filehandle) Sync() error {
136 // Sync the containing filesystem.
140 func (f *filehandle) Snapshot() (*Subtree, error) {
142 return nil, ErrInvalidOperation
144 node, err := f.inode.Snapshot()
145 return &Subtree{inode: node}, err
148 func (f *filehandle) Splice(r *Subtree) error {
150 return ErrReadOnlyFile
152 return f.inode.Splice(r.inode)