commit bf3e347ce5235dad9eeb585fc84b0b2638c7ef8b
parent 500acf7e5832f0ed06e6a2a2fa502c0054020d76
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sun, 20 Aug 2023 16:57:31 +0900
change QidPool
Diffstat:
| M | file.go | | | 11 | +++-------- |
| M | fs.go | | | 15 | +++------------ |
| M | pool.go | | | 46 | +--------------------------------------------- |
| A | qid_plan9.go | | | 2 | ++ |
| A | qid_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