qid.go (1519B)
1 package iofs 2 3 import ( 4 "fmt" 5 "time" 6 7 "git.mtkn.jp/lib9p" 8 ) 9 10 type fileID string 11 12 type qidRec struct { 13 qid *lib9p.Qid 14 mtime time.Time 15 } 16 17 type QidPool struct { 18 m map[fileID]*qidRec 19 nextQid uint64 20 } 21 22 func (f *File) id() (fileID, error) { 23 return fileID(f.path), nil 24 } 25 26 func allocQidPool() *QidPool { 27 return &QidPool{ 28 m: make(map[fileID]*qidRec), 29 } 30 } 31 32 func (pool *QidPool) lookup(f *File) (lib9p.Qid, bool) { 33 id, err := f.id() 34 if err != nil { 35 return lib9p.Qid{}, false 36 } 37 qreq, ok := pool.m[id] 38 if !ok { 39 return lib9p.Qid{}, false 40 } 41 42 fsfile, err := f.fs.fs.Open(f.path) 43 if err != nil { 44 return lib9p.Qid{}, false 45 } 46 defer fsfile.Close() 47 stat, err := fsfile.Stat() 48 if err != nil { 49 return lib9p.Qid{}, false 50 } 51 mtime := stat.ModTime() 52 if qreq.mtime.Before(mtime) { 53 qreq.qid.Vers++ 54 qreq.mtime = mtime 55 } 56 return *qreq.qid, ok 57 } 58 59 func (pool *QidPool) alloc(f *File) (lib9p.Qid, error) { 60 id, err := f.id() 61 if err != nil { 62 return lib9p.Qid{}, fmt.Errorf("get id: %v", err) 63 } 64 fsfile, err := f.fs.fs.Open(f.path) 65 if err != nil { 66 return lib9p.Qid{}, err 67 } 68 defer fsfile.Close() 69 fi, err := fsfile.Stat() 70 if err != nil { 71 return lib9p.Qid{}, fmt.Errorf("stat %v: %v", f, err) 72 } 73 qtype := lib9p.FSModeToQidType(fi.Mode()) 74 qid := &lib9p.Qid{ 75 Path: pool.nextQid, 76 Type: qtype, 77 } 78 pool.m[id] = &qidRec{qid: qid, mtime: fi.ModTime()} 79 pool.nextQid++ 80 return *qid, nil 81 } 82 83 func (pool *QidPool) delete(f *File) { 84 id, err := f.id() 85 if err != nil { 86 return 87 } 88 delete(pool.m, id) 89 }