1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
14 type filehandle struct {
20 unreaddirs []os.FileInfo
23 func (f *filehandle) Read(p []byte) (n int, err error) {
25 return 0, ErrWriteOnlyMode
28 defer f.inode.RUnlock()
29 n, f.ptr, err = f.inode.Read(p, f.ptr)
33 func (f *filehandle) Seek(off int64, whence int) (pos int64, err error) {
34 size := f.inode.Size()
45 return f.ptr.off, ErrNegativeOffset
47 if ptr.off != f.ptr.off {
49 // force filenode to recompute f.ptr fields on next
56 func (f *filehandle) Truncate(size int64) error {
57 return f.inode.Truncate(size)
60 func (f *filehandle) Write(p []byte) (n int, err error) {
62 return 0, ErrReadOnlyFile
65 defer f.inode.Unlock()
66 if fn, ok := f.inode.(*filenode); ok && f.append {
68 off: fn.fileinfo.size,
69 segmentIdx: len(fn.segments),
71 repacked: fn.repacked,
74 n, f.ptr, err = f.inode.Write(p, f.ptr)
78 func (f *filehandle) Repack(ctx context.Context, opts RepackOptions) (int, error) {
79 dn, ok := f.inode.(*dirnode)
81 return 0, ErrNotADirectory
85 return dn.fs.repackTree(ctx, opts, dn)
88 // dirEntry implements fs.DirEntry, see (*filehandle)ReadDir().
89 type dirEntry struct {
93 func (ent dirEntry) Type() fs.FileMode {
94 return ent.Mode().Type()
96 func (ent dirEntry) Info() (fs.FileInfo, error) {
100 // ReadDir implements fs.ReadDirFile.
101 func (f *filehandle) ReadDir(count int) ([]fs.DirEntry, error) {
102 fis, err := f.Readdir(count)
106 ents := make([]fs.DirEntry, len(fis))
107 for i, fi := range fis {
108 ents[i] = dirEntry{fi}
113 func (f *filehandle) Readdir(count int) ([]os.FileInfo, error) {
114 if !f.inode.IsDir() {
115 return nil, ErrInvalidOperation
118 return f.inode.Readdir()
120 if f.unreaddirs == nil {
122 f.unreaddirs, err = f.inode.Readdir()
127 if len(f.unreaddirs) == 0 {
130 if count > len(f.unreaddirs) {
131 count = len(f.unreaddirs)
133 ret := f.unreaddirs[:count]
134 f.unreaddirs = f.unreaddirs[count:]
138 func (f *filehandle) Stat() (os.FileInfo, error) {
139 return f.inode.FileInfo(), nil
142 func (f *filehandle) Close() error {
146 func (f *filehandle) Sync() error {
147 // Sync the containing filesystem.
151 func (f *filehandle) Snapshot() (*Subtree, error) {
153 return nil, ErrInvalidOperation
155 node, err := f.inode.Snapshot()
156 return &Subtree{inode: node}, err
159 func (f *filehandle) Splice(r *Subtree) error {
161 return ErrReadOnlyFile
163 return f.inode.Splice(r.inode)