commit d5ed46010c01c045ca6f35aba4b81ef019337e0a
parent 1d8bcf63fb2ef276c5dfeb7e911d997f4f2e02d2
Author: Matsuda Kenji <info@mtkn.jp>
Date: Mon, 22 Jan 2024 08:51:06 +0900
delete client fid and embed it to File
Diffstat:
5 files changed, 67 insertions(+), 77 deletions(-)
diff --git a/client/client.go b/client/client.go
@@ -21,8 +21,8 @@ type Client struct {
// Uname is used to communicate with a server.
uname string
- // FPool is the fidPool which hold the list of open fids.
- fPool *fidPool
+ // FPool is the filePool which hold the list of outstanding files.
+ fPool *filePool
// RPool is the set of all outstanding requests.
rPool *reqPool
@@ -30,8 +30,8 @@ type Client struct {
// Txc is used to send a reqest to the multiplexer goroutine
txc chan<- *req
- // RootFid is the fid of the root of the file system.
- rootFid *fid
+ // Root is the root file of the file system.
+ root *File
// Wg is the WaitGroup of all goroutines evoked by this client and its
// descendants.
@@ -52,7 +52,7 @@ func NewClient(ctx context.Context, mSize uint32, uname string, r io.Reader, w i
msize: mSize,
mSizeLock: new(sync.Mutex),
uname: uname,
- fPool: allocClientFidPool(),
+ fPool: newFilePool(),
rPool: newReqPool(),
wg: new(sync.WaitGroup),
done: ctx.Done(),
diff --git a/client/client_test.go b/client/client_test.go
@@ -59,7 +59,7 @@ func newClientForTest(ctx context.Context, msize uint32, uname string) (*Client,
msize: msize,
mSizeLock: new(sync.Mutex),
uname: uname,
- fPool: allocClientFidPool(),
+ fPool: newFilePool(),
rPool: newReqPool(),
wg: new(sync.WaitGroup),
}
diff --git a/client/fid.go b/client/fid.go
@@ -7,35 +7,22 @@ import (
"git.mtkn.jp/lib9p"
)
-// fid represents the Fid in the client side.
-type fid struct {
- fid uint32
- omode lib9p.OpenMode // -1 for not open
- offset uint64
- file *File
-}
-
-func newClientFid(id uint32) *fid {
- return &fid{
- fid: id,
- omode: -1,
- offset: 0,
- }
-}
-
-type fidPool struct {
- m map[uint32]*fid
+type filePool struct {
+ m map[uint32]*File
*sync.Mutex
}
-func allocClientFidPool() *fidPool {
- return &fidPool{
- make(map[uint32]*fid),
+func newFilePool() *filePool {
+ return &filePool{
+ make(map[uint32]*File),
new(sync.Mutex),
}
}
-func (pool *fidPool) lookup(fid uint32) (*fid, bool) {
+func (pool *filePool) lookup(fid uint32) (*File, bool) {
+ if fid == lib9p.NOFID {
+ return nil, false
+ }
pool.Lock()
defer pool.Unlock()
f, ok := pool.m[fid]
@@ -43,8 +30,8 @@ func (pool *fidPool) lookup(fid uint32) (*fid, bool) {
}
// NextFid does not lock pool. Lock it before calling this function.
-func (pool *fidPool) nextFid() (uint32, error) {
- for i := uint32(0); i < i+1; i++ {
+func (pool *filePool) nextFid() (uint32, error) {
+ for i := uint32(0); i < lib9p.NOFID; i++ {
if _, ok := pool.m[i]; !ok {
return i, nil
}
@@ -52,41 +39,42 @@ func (pool *fidPool) nextFid() (uint32, error) {
return 0, fmt.Errorf("run out of fid")
}
-func (pool *fidPool) add() (*fid, error) {
+func (pool *filePool) add() (*File, error) {
pool.Lock()
defer pool.Unlock()
fid, err := pool.nextFid()
if err != nil {
return nil, err
}
- if _, ok := pool.m[fid]; ok {
- return nil, fmt.Errorf("fid already in use.")
+ f := &File{
+ fid: fid,
+ omode: -1,
+ offset: 0,
}
- f := newClientFid(fid)
pool.m[fid] = f
return f, nil
}
-func (pool *fidPool) delete(fid uint32) {
+func (pool *filePool) delete(fid uint32) {
pool.Lock()
defer pool.Unlock()
delete(pool.m, fid)
}
-func (pool *fidPool) String() string {
+func (pool *filePool) String() string {
pool.Lock() // TODO: need?
defer pool.Unlock()
s := "{"
- for fnum, fstruct := range pool.m {
- if fstruct.file == nil {
- s += fmt.Sprintf(" [%d]<nil>", fnum)
+ for fid, file := range pool.m {
+ if file == nil { // TODO: need?
+ s += fmt.Sprintf(" [%d]<nil>", fid)
continue
}
- st, err := fstruct.file.Stat()
+ st, err := file.Stat()
if err != nil {
panic(err)
}
- s += fmt.Sprintf(" [%d]%v", fnum, st.Name())
+ s += fmt.Sprintf(" [%d]%v", fid, st.Name())
}
s += "}"
return s
diff --git a/client/file.go b/client/file.go
@@ -12,7 +12,9 @@ import (
type File struct {
name string
path string // must not contain trailing slash.
- fid *fid
+ fid uint32
+ omode lib9p.OpenMode
+ offset uint64
qid lib9p.Qid
iounit uint32
fs *FS
@@ -24,7 +26,7 @@ func (cf *File) Stat() (*lib9p.FileInfo, error) {
if err != nil {
return nil, err
}
- st, err := cf.fs.c.Stat(tag, cf.fid.fid)
+ st, err := cf.fs.c.Stat(tag, cf.fid)
cf.fs.tPool.delete(tag)
if err != nil {
return nil, err
@@ -38,7 +40,7 @@ func (cf *File) WStat(stat *lib9p.Stat) error {
if err != nil {
return err
}
- err = cf.fs.c.Wstat(tag, cf.fid.fid, stat)
+ err = cf.fs.c.Wstat(tag, cf.fid, stat)
cf.fs.tPool.delete(tag)
return err
}
@@ -49,21 +51,21 @@ func (cf *File) Close() error {
if err != nil {
return err
}
- err = cf.fs.c.Clunk(tag, cf.fid.fid)
+ err = cf.fs.c.Clunk(tag, cf.fid)
cf.fs.tPool.delete(tag)
- cf.fs.c.fPool.delete(cf.fid.fid)
- cf.fid = nil
+ cf.fs.c.fPool.delete(cf.fid)
+ cf.fid = lib9p.NOFID
return err
}
func (cf *File) Read(b []byte) (int, error) {
- if cf.fid.omode == -1 {
+ if cf.omode == -1 {
return 0, errors.New("not open")
}
if len(b) == 0 {
return 0, nil
}
- if cf.fid.omode&3 != lib9p.OREAD && cf.fid.omode&3 != lib9p.ORDWR {
+ if cf.omode&3 != lib9p.OREAD && cf.omode&3 != lib9p.ORDWR {
return 0, lib9p.ErrPerm
}
count := len(b)
@@ -79,13 +81,13 @@ func (cf *File) Read(b []byte) (int, error) {
if err != nil {
return 0, err
}
- buf, err := cf.fs.c.Read(tag, cf.fid.fid, cf.fid.offset, c)
+ buf, err := cf.fs.c.Read(tag, cf.fid, cf.offset, c)
cf.fs.tPool.delete(tag)
var i int
for i = 0; i < len(buf); i++ {
b[cur+i] = buf[i]
}
- cf.fid.offset += uint64(i)
+ cf.offset += uint64(i)
cur += i
if err != nil {
return cur, err
@@ -100,13 +102,13 @@ func (cf *File) Read(b []byte) (int, error) {
}
func (cf *File) Write(b []byte) (int, error) {
- if cf.fid.omode == -1 {
+ if cf.omode == -1 {
return 0, errors.New("not open")
}
if len(b) == 0 {
return 0, nil
}
- if cf.fid.omode&3 != lib9p.OWRITE && cf.fid.omode&3 != lib9p.ORDWR {
+ if cf.omode&3 != lib9p.OWRITE && cf.omode&3 != lib9p.ORDWR {
return 0, lib9p.ErrPerm
}
count := len(b)
@@ -122,9 +124,9 @@ func (cf *File) Write(b []byte) (int, error) {
if err != nil {
return 0, err
}
- n, err := cf.fs.c.Write(tag, cf.fid.fid, cf.fid.offset, c, b[cur:cur+int(c)])
+ n, err := cf.fs.c.Write(tag, cf.fid, cf.offset, c, b[cur:cur+int(c)])
cf.fs.tPool.delete(tag)
- cf.fid.offset += uint64(n)
+ cf.offset += uint64(n)
cur += int(n)
if err != nil {
return cur, err
@@ -138,7 +140,7 @@ func (cf *File) ReadDir(n int) ([]fs.DirEntry, error) {
if cf.qid.Type&lib9p.QTDIR == 0 {
return nil, errors.New("not a directory")
}
- if cf.fid.omode == -1 {
+ if cf.omode == -1 {
return nil, errors.New("not open")
}
var (
@@ -152,14 +154,14 @@ func (cf *File) ReadDir(n int) ([]fs.DirEntry, error) {
if err != nil {
break
}
- data, err = cf.fs.c.Read(tag, cf.fid.fid, cf.fid.offset, cf.iounit)
+ data, err = cf.fs.c.Read(tag, cf.fid, cf.offset, cf.iounit)
cf.fs.tPool.delete(tag)
if err != nil {
break
} else if len(data) == 0 {
break
}
- cf.fid.offset += uint64(len(data))
+ cf.offset += uint64(len(data))
for len(data) > 0 {
st := lib9p.NewStat(data)
data = data[2+st.Size():]
diff --git a/client/fs.go b/client/fs.go
@@ -33,14 +33,14 @@ func (fsys *FS) OpenFile(name string, flag int) (lib9p.File, error) {
if err != nil {
return nil, err
}
- qid, iounit, err = fsys.c.Open(tag, f.fid.fid, lib9p.FlagToMode(flag))
+ qid, iounit, err = fsys.c.Open(tag, f.fid, lib9p.FlagToMode(flag))
fsys.tPool.delete(tag)
if err != nil {
f.Close()
return nil, fmt.Errorf("open: %v", err)
}
}
- f.fid.omode = lib9p.FlagToMode(flag)
+ f.omode = lib9p.FlagToMode(flag)
f.qid = qid
f.iounit = iounit
return f, nil
@@ -66,9 +66,9 @@ func CleanPath(name string) string {
// returns the corresponding file.
// returned file is not open.
func (fsys *FS) walkFile(name string) (*File, error) {
- fid, err := fsys.c.fPool.add()
+ f, err := fsys.c.fPool.add()
if err != nil {
- return nil, fmt.Errorf("add fid: %v", err)
+ return nil, fmt.Errorf("add file: %v", err)
}
var wname []string
if name != "." {
@@ -78,31 +78,27 @@ func (fsys *FS) walkFile(name string) (*File, error) {
if err != nil {
return nil, err
}
- wqid, err := fsys.c.Walk(tag, fsys.c.rootFid.fid, fid.fid, wname)
+ wqid, err := fsys.c.Walk(tag, fsys.c.root.fid, f.fid, wname)
fsys.tPool.delete(tag)
if err != nil {
return nil, fmt.Errorf("walk: %v", err)
}
if len(wqid) < len(wname) {
- fsys.c.fPool.delete(fid.fid)
+ fsys.c.fPool.delete(f.fid)
return nil, fmt.Errorf("not found")
}
var qid lib9p.Qid
if name == "." {
- qid = lib9p.Qid{}
+ qid = lib9p.Qid{} // TODO: ?? why it is not fsys.c.root.qid?
} else if len(wqid) > 0 {
qid = wqid[len(wqid)-1]
} else {
return nil, fmt.Errorf("invalid wqid: %v", wqid)
}
- f := &File{
- name: path.Base(name),
- path: name,
- fid: fid,
- qid: qid,
- fs: fsys,
- }
- fid.file = f
+ f.name = path.Base(name)
+ f.path = name
+ f.qid = qid
+ f.fs = fsys
return f, nil
}
@@ -138,19 +134,23 @@ func Mount(ctx context.Context, r io.Reader, w io.Writer, uname, aname string) (
cfs.c.setMSize(rmSize)
}
// TODO: auth
- fid, err := cfs.c.fPool.add()
+ f, err := cfs.c.fPool.add()
if err != nil {
- return nil, fmt.Errorf("add fid: %v", err)
+ return nil, fmt.Errorf("add file: %v", err)
}
tag, err := cfs.tPool.add()
if err != nil {
return nil, err
}
- _, err = cfs.c.Attach(tag, fid.fid, lib9p.NOFID, uname, aname)
+ qid, err := cfs.c.Attach(tag, f.fid, lib9p.NOFID, uname, aname)
cfs.tPool.delete(tag)
if err != nil {
return nil, fmt.Errorf("attach: %v", err)
}
- cfs.c.rootFid = fid
+ f.name = "."
+ f.path = "."
+ f.qid = qid
+ f.fs = cfs
+ cfs.c.root = f
return cfs, nil
}