lib9p

Go 9P library.
Log | Files | Refs | LICENSE

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 }