diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2026-03-14 17:06:34 -0400 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2026-03-14 17:06:34 -0400 |
| commit | a7de24661c55a026dd208c8a62c50d6682d39859 (patch) | |
| tree | 25b9abd8952f7f00db80cf4ac5271913773a8e81 | |
| parent | b57a199eb44dff5af3bdb7866b818544e1d270ee (diff) | |
| download | buth-a7de24661c55a026dd208c8a62c50d6682d39859.zip | |
authfs: implement Rwalk, Rcreate
| -rw-r--r-- | back/cmd/authfs/authfs.go | 90 | ||||
| -rw-r--r-- | back/cmd/authfs/err.go | 7 | ||||
| -rw-r--r-- | back/cmd/authfs/sessdir.go | 9 |
3 files changed, 89 insertions, 17 deletions
diff --git a/back/cmd/authfs/authfs.go b/back/cmd/authfs/authfs.go index bf6e340..5493606 100644 --- a/back/cmd/authfs/authfs.go +++ b/back/cmd/authfs/authfs.go @@ -12,13 +12,16 @@ import ( type File interface { Qid() (p9.QID, error) - Open(mode p9.Mode) error - // TODO + Stat() (p9.Dir, error) + Open(p9.Mode) error + Read(p9.Offset, p9.Count) ([]byte, error) + Write(p9.Offset, []byte) (p9.Count, error) } type Dir interface { File - // TODO: walk, create + Create(string, p9.Perm, p9.Mode) (File, error) + Walk(string) (File, error) } // Authfs is the root p9.NineServer. @@ -52,6 +55,13 @@ func (fs *Authfs) Close() { fs.SessionsDir.Close() } +func (fs *Authfs) Rversion(msize p9.MaxSize, version string) (p9.MaxSize, string, error) { + if version != "9P2000" { + return 0, "", fmt.Errorf("%v not supported; only 9P2000", version) + } + return msize, version, nil +} + func (fs *Authfs) Rattach(fid, afid p9.FID, uname, aname string) (p9.QID, error) { if afid != p9.NOFID { return p9.QID{}, fmt.Errorf("authfs: no authentication required") @@ -111,16 +121,38 @@ func (fs *Authfs) Rattach(fid, afid p9.FID, uname, aname string) (p9.QID, error) return qid, nil } -func (fs *Authfs) attach(fid p9.FID, f File) error { - fs.mu.Lock() - defer fs.mu.Unlock() +func (fs *Authfs) Rwalk(fid, newfid p9.FID, paths []string) ([]p9.QID, error) { + f, err := fs.getFile(fid) + if err != nil { + return nil, err + } - if _, exists := fs.files[fid]; exists { - return ErrFidExist + var qids []p9.QID + for i := range paths { + dir, ok := f.(Dir) + if !ok { + return qids, ErrWalkNonDir + } + f, err = dir.Walk(paths[i]) + if err != nil { + return qids, err + } + qid, err := f.Qid() + if err != nil { + return qids, err + } + qids = append(qids, qid) } - fs.files[fid] = f - return nil + fs.mu.Lock() + defer fs.mu.Unlock() + if newfid != fid { + if _, ok := fs.files[newfid]; ok { + return nil, fmt.Errorf("newfid in use: walk to %v, fid %v, newfid %v", paths, fid, newfid) + } + } + fs.files[newfid] = f + return qids, nil } func (fs *Authfs) Rclunk(fid p9.FID) error { @@ -134,15 +166,45 @@ func (fs *Authfs) Rclunk(fid p9.FID) error { return nil } -func (fs *Authfs) Ropen(fid p9.FID, mode p9.Mode) (p9.QID, error) { +func (fs *Authfs) Ropen(fid p9.FID, mode p9.Mode) (p9.QID, p9.MaxSize, error) { f, err := fs.getFile(fid) if err != nil { - return p9.QID{}, err + return p9.QID{}, 0, err } if err := f.Open(mode); err != nil { - return p9.QID{}, err + return p9.QID{}, 0, err + } + qid, err := f.Qid() + return qid, 0, err +} + +func (fs *Authfs) Rcreate(fid p9.FID, name string, perm p9.Perm, mode p9.Mode) (p9.QID, p9.MaxSize, error) { + f, err := fs.getFile(fid) + if err != nil { + return p9.QID{}, 0, err + } + dir, ok := f.(Dir) + if !ok { + return p9.QID{}, 0, ErrCreateNonDir + } + child, err := dir.Create(name, perm, mode) + if err != nil { + return p9.QID{}, 0, err } - return f.Qid() + qid, err := child.Qid() + return qid, 0, err +} + +func (fs *Authfs) Rflush(o p9.Tag) error { return nil } + +func (fs *Authfs) attach(fid p9.FID, f File) error { + fs.mu.Lock() + defer fs.mu.Unlock() + if _, exists := fs.files[fid]; exists { + return ErrFidExist + } + fs.files[fid] = f + return nil } func (fs *Authfs) getFile(fid p9.FID) (File, error) { diff --git a/back/cmd/authfs/err.go b/back/cmd/authfs/err.go index 4f4dbbf..7c2b192 100644 --- a/back/cmd/authfs/err.go +++ b/back/cmd/authfs/err.go @@ -3,9 +3,12 @@ package main import "errors" var ( - ErrFileExist = errors.New("file already exists") - ErrFileNotExist = errors.New("file does not exist") + ErrCreateNonDir = errors.New("cannot create in non-directory") ErrFidExist = errors.New("fid already exists") ErrFidNotExist = errors.New("fid does not exist") + ErrFileExist = errors.New("file already exists") + ErrFileNotExist = errors.New("file does not exist") + ErrNewFidExist = errors.New("newfid already exists") ErrPerm = errors.New("permission denied") + ErrWalkNonDir = errors.New("cannot walk in non-directory") ) diff --git a/back/cmd/authfs/sessdir.go b/back/cmd/authfs/sessdir.go index 22d8202..dbfb477 100644 --- a/back/cmd/authfs/sessdir.go +++ b/back/cmd/authfs/sessdir.go @@ -40,7 +40,14 @@ func (dir *SessionsDir) Get(id auth.SessId) (*Session, bool) { dir.mu.Lock() defer dir.mu.Unlock() sess, ok := dir.sessions[id] - return sess, ok + if !ok { + return nil, false + } + if !sess.IsActive() { + delete(dir.sessions, id) + return nil, false + } + return sess, true } // Owner returns the owner of the given session if it exists, or false if it doesn't. |