lib9p

Go 9P library.
Log | Files | Refs

commit 42c5456c307858ab7a7a6693cfe41764a9d9006a
parent 287a65746ba4a3ad22b9c48ee3293e9ddde96fbc
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Fri,  8 Sep 2023 14:26:36 +0900

implement diskfs

Diffstat:
Mdiskfs/file.go | 94++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 48 insertions(+), 46 deletions(-)

diff --git a/diskfs/file.go b/diskfs/file.go @@ -13,10 +13,11 @@ import ( ) type File struct { - fs *FS // file system to which this file belongs - file *os.File // underlying file - path string // absolute path from the root of the fs. - children []lib9p.File + fs *FS // file system to which this file belongs + file *os.File // underlying file + path string // absolute path from the root of the fs. + childEntry []*lib9p.DirEntry + diroff int // directory offset for ReadDir() } func openFile(fsys *FS, fpath string) (*File, error) { @@ -24,10 +25,38 @@ func openFile(fsys *FS, fpath string) (*File, error) { if err != nil { return nil, fmt.Errorf("open fs: %v", err) } + + fi, err := file.Stat() + if err != nil { + return nil, fmt.Errorf("stat: %v", err) + } + var childEntry []*lib9p.DirEntry + if fi.IsDir() { + dir := file.(fs.ReadDirFile) + de, err := dir.ReadDir(-1) + if err != nil { + return nil, fmt.Errorf("read dir: %v", err) + } + childEntry = make([]*lib9p.DirEntry, len(de)) + for i := 0; i < len(de); i++ { + info, err := de[i].Info() + if err != nil { + return nil, fmt.Errorf("info: %v", err) + } + sys := info.Sys().(*syscall.Stat_t) + id := fileID{ + device: sys.Dev, + inode: sys.Ino, + } + stat := fiStat(fsys.qidPool, id, info) + childEntry[i] = &lib9p.DirEntry{Stat: *stat} + } + } f := &File{ - fs: fsys, - file: file.(*os.File), - path: fpath, + fs: fsys, + file: file.(*os.File), + path: fpath, + childEntry: childEntry, } return f, nil } @@ -89,13 +118,16 @@ func (f *File) Parent() (lib9p.File, error) { } func (f *File) Child() ([]lib9p.File, error) { - if f.children == nil { - _, err := f.ReadDir(-1) + files := make([]lib9p.File, len(f.childEntry)) + for i := 0; i < len(f.childEntry); i++ { + cpath := path.Join(f.path, f.childEntry[i].Name()) + child, err := f.fs.Open(cpath) if err != nil { - return f.children, fmt.Errorf("read dir: %v") + return files, fmt.Errorf("open child unko: %v", err) } + files[i] = child } - return f.children, nil + return files, nil } func (f *File) ReadAt(p []byte, off int64) (int, error) { @@ -103,41 +135,11 @@ func (f *File) ReadAt(p []byte, off int64) (int, error) { } func (f *File) ReadDir(n int) ([]*lib9p.DirEntry, error) { - fsde, err := f.file.ReadDir(n) - if err != nil { - return nil, err - } - if len(fsde) == 0 { - if f.children == nil { - f.children = make([]lib9p.File, 0) - } - de := make([]*lib9p.DirEntry, len(f.children)) - for i := 0; i < len(f.children); i++ { - fi, err := f.children[i].Stat() - if err != nil { - return de, fmt.Errorf("stat: %v", err) - } - de[i] = &lib9p.FileInfo{*fi.Sys().(*lib9p.Stat)} - } - return de, nil + childEntry := f.childEntry[f.diroff:] + if n < 0 || len(childEntry) < n { + n = len(childEntry) } - de := make([]*lib9p.DirEntry, len(fsde)) - children := make([]lib9p.File, len(fsde)) - for i := 0; i < len(de); i++ { - info, err := fsde[i].Info() - if err != nil { - return de, err - } - id := idFromInfo(info) - de[i] = &lib9p.FileInfo{*fiStat(f.fs.qidPool, id, info)} - childPath := path.Join(f.PathName(), info.Name()) - child, err := f.fs.Open(childPath) - if err != nil { - return de, fmt.Errorf("open: %v", err) - } - children[i] = child - } - f.children = append(f.children, children...) - return de, nil + f.diroff += n + return childEntry[:n], nil }