lib9p

Go 9P library.
Log | Files | Refs

commit bf3e347ce5235dad9eeb585fc84b0b2638c7ef8b
parent 500acf7e5832f0ed06e6a2a2fa502c0054020d76
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sun, 20 Aug 2023 16:57:31 +0900

change QidPool

Diffstat:
Mfile.go | 11+++--------
Mfs.go | 15+++------------
Mpool.go | 46+---------------------------------------------
Aqid_plan9.go | 2++
Aqid_unix.go | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 92 insertions(+), 65 deletions(-)

diff --git a/file.go b/file.go @@ -195,10 +195,6 @@ func openFile(fsys *FS, fpath string) (*File, error) { if err != nil { return nil, fmt.Errorf("open fs: %v", err) } - fsfi, err := file.Stat() - if err != nil { - return nil, fmt.Errorf("stat file: %v", err) - } f := &File{ fs: fsys, file: file, @@ -215,15 +211,14 @@ func openFile(fsys *FS, fpath string) (*File, error) { */ } - qtype := fsModeToQidType(fsfi.Mode()) - q, ok := fsys.qidPool.lookup(fsfi) + q, ok := fsys.qidPool.lookup(f) if !ok { - q, err = fsys.qidPool.alloc(fsfi, qtype) + q, err = fsys.qidPool.alloc(f) if err != nil { return nil, fmt.Errorf("alloc qid for file %v: %v", file, err) } } - f.Qid = *q + f.Qid = q return f, nil } diff --git a/fs.go b/fs.go @@ -28,24 +28,15 @@ func (fsys *FS) walk(root string, wnames []string) ([]*Qid, error) { if err != nil { return wqids, err } - fi, err := f.Stat() - if err != nil { - return wqids, fmt.Errorf("stat file %v: %v", f, err) - } - qid, ok := fsys.qidPool.lookup(fi.info) // TODO: use os.SameFile + qid, ok := fsys.qidPool.lookup(f) // TODO: use os.SameFile if !ok { - s, err := f.file.Stat() - if err != nil { - return wqids, err - } - qtype := fsModeToQidType(s.Mode()) - qid, err = fsys.qidPool.alloc(s, qtype) + qid, err = fsys.qidPool.alloc(f) if err != nil { return wqids, err } } - wqids[i] = qid + wqids[i] = &qid } return wqids, nil } diff --git a/pool.go b/pool.go @@ -2,52 +2,8 @@ package lib9p import ( "fmt" - "io/fs" -) - -type QidPool struct { - m map[fs.FileInfo]*Qid - nextQid uint64 -} - -func allocQidPool() *QidPool { - q := new(QidPool) - q.m = make(map[fs.FileInfo]*Qid) - return q -} - -func (pool *QidPool) lookup(fi fs.FileInfo) (*Qid, bool) { - for fi1, qid := range pool.m { - if sameFile(fi, fi1) { - return qid, true - } - } - return nil, false -} - -func (pool *QidPool) delete(fi fs.FileInfo) { - for fi1, _ := range pool.m { - if sameFile(fi, fi1) { - delete(pool.m, fi1) - } - } -} - - -func (pool *QidPool) alloc(fi fs.FileInfo, t QidType) (*Qid, error) { - if _, ok := pool.lookup(fi); ok { - return nil, fmt.Errorf("qid already exist for file %s", fi.Name()) - } - - q := &Qid{t: t, path:pool.nextQid} - pool.nextQid++ - if q.path > pool.nextQid { - panic("qid overflow") - } - pool.m[fi] = q - return q, nil -} +) type FidPool struct { m map[uint32]*Fid diff --git a/qid_plan9.go b/qid_plan9.go @@ -0,0 +1 @@ +package lib9p +\ No newline at end of file diff --git a/qid_unix.go b/qid_unix.go @@ -0,0 +1,82 @@ +package lib9p + +import ( + "fmt" + "syscall" +) + +type fileID struct { + device uint64 + inode uint64 +} + +type QidPool struct { + m map[fileID]Qid + nextQid uint64 +} + +func (f *File) id() (fileID, error) { + fi, err := f.file.Stat() + if err != nil { + return fileID{}, err + } + sys := fi.Sys().(*syscall.Stat_t) + id := fileID{ + device: sys.Dev, + inode: sys.Ino, + } + return id, nil +} + +func (f *File) qid() (Qid, error) { + qid, ok := f.fs.qidPool.lookup(f) + if ok { + return qid, nil + } + qid, err := f.fs.qidPool.alloc(f) + if err != nil { + return Qid{}, fmt.Errorf("alloc qid: %v", err) + } + return qid, nil +} + +func allocQidPool() *QidPool { + return &QidPool{ + m: make(map[fileID]Qid), + } +} + +func (pool *QidPool) lookup(f *File) (Qid, bool) { + id, err := f.id() + if err != nil { + return Qid{}, false + } + qid, ok := pool.m[id] + return qid, ok +} + +func (pool *QidPool) alloc(f *File) (Qid, error) { + id, err := f.id() + if err != nil { + return Qid{}, fmt.Errorf("get id: %v", err) + } + fi, err := f.file.Stat() + if err != nil { + return Qid{}, fmt.Errorf("stat %v: %v", f, err) + } + qtype := fsModeToQidType(fi.Mode()) + qid := Qid{ + path: pool.nextQid, + t: qtype, + } + pool.m[id] = qid + return qid, nil +} + +func (pool *QidPool) delete(f *File) { + id, err := f.id() + if err != nil { + return + } + delete(pool.m, id) +} +\ No newline at end of file