lib9p

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

commit 5944c1fe580363b2e373e7ab4fbe420c59e48a02
parent 54b8547e46c57f6a208bf3efd5a40e9cca9df833
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 16 Dec 2023 09:11:14 +0900

cache gid
assuming that gids are not changed by other program

Diffstat:
Mdiskfs/stat_unix.go | 35++++++++++++++++++++++++++---------
1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/diskfs/stat_unix.go b/diskfs/stat_unix.go @@ -52,6 +52,12 @@ func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat { } } +var gidCache map[fileID]string + +func init() { + gidCache = make(map[fileID]string) +} + // Stat is real implementation of File.Stat. func (f *File) stat() (*lib9p.FileInfo, error) { ospath := filepath.Join(f.fs.rootPath, f.path) @@ -69,26 +75,30 @@ func (f *File) stat() (*lib9p.FileInfo, error) { panic(fmt.Errorf("alloc qid: %v", err)) } } + stat_t := fsfi.Sys().(*syscall.Stat_t) stat.Qid = qid stat.Length = fsfi.Size() stat.Mode = fsfi.Mode() stat.Name = fsfi.Name() - // TODO: Unix specific. - stat.Atime = uint32(fsfi.Sys().(*syscall.Stat_t).Atim.Sec) - stat.Mtime = uint32(fsfi.Sys().(*syscall.Stat_t).Mtim.Sec) - uid := fsfi.Sys().(*syscall.Stat_t).Uid + stat.Atime = uint32(stat_t.Atim.Sec) + stat.Mtime = uint32(stat_t.Mtim.Sec) + uid := stat_t.Uid usr, err := user.LookupId(strconv.Itoa(int(uid))) if err != nil { return nil, fmt.Errorf("LookupId(%d): %v", uid, err) } stat.Uid = usr.Username - gid := fsfi.Sys().(*syscall.Stat_t).Gid + gid := stat_t.Gid // TODO: this call is time consuming. - group, err := user.LookupGroupId(strconv.Itoa(int(gid))) - if err != nil { - return nil, fmt.Errorf("LookupGroupId(%d): %v", gid, err) + fileid := fileID{device: stat_t.Dev, inode: stat_t.Ino} + if _, ok := gidCache[fileid]; !ok { + group, err := user.LookupGroupId(strconv.Itoa(int(gid))) + if err != nil { + return nil, fmt.Errorf("LookupGroupId(%d): %v", gid, err) + } + gidCache[fileid] = group.Name } - stat.Gid = group.Name + stat.Gid = gidCache[fileid] stat.Muid = "" return &lib9p.FileInfo{stat}, nil } @@ -163,6 +173,13 @@ func (f *File) wstat(s *lib9p.Stat) error { if err := file.Chown(u, g); err != nil { return fmt.Errorf("chown: %v", err) } + st, err := file.Stat() + if err != nil { + return fmt.Errorf("stat: %v", err) + } + stat_t := st.Sys().(*syscall.Stat_t) + fileid := fileID{device: stat_t.Dev, inode: stat_t.Ino} + gidCache[fileid] = s.Gid } if s.Name != oldStat.Name { // TODO: check neither Names contains "/"