commit d177d8ad7a393f210febe989023a2b4b207a34c2
parent 6c42146499ecb3aba36c46a0a621e59389137434
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 29 Nov 2023 17:40:37 +0900
fix wstat
Diffstat:
1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/diskfs/stat_unix.go b/diskfs/stat_unix.go
@@ -95,28 +95,20 @@ func (f *File) stat() (*lib9p.FileInfo, error) {
// wstat is the real implementation of File.WStat.
// TODO: when error occurs, file stat should be restored.
func (f *File) wstat(s *lib9p.Stat) error {
- file, err := os.OpenFile(path.Join(f.fs.rootPath, f.path), os.O_RDWR, 0)
- if err != nil {
- return err
- }
- defer file.Close()
-
+ var file *os.File
fi, err := f.Stat()
if err != nil {
return fmt.Errorf("stat: %v", err)
}
-
oldStat := fi.Sys().(*lib9p.Stat)
-
- if s.Name != oldStat.Name {
- // TODO: check neither Names contains "/"
- oldpath := path.Join(f.fs.rootPath, path.Dir(f.path), oldStat.Name)
- newpath := path.Join(f.fs.rootPath, path.Dir(f.path), s.Name)
- if err := os.Rename(oldpath, newpath); err != nil {
- return fmt.Errorf("rename: %v", err)
- }
- }
if s.Length != oldStat.Length {
+ if file == nil {
+ file, err = os.OpenFile(path.Join(f.fs.rootPath, f.path), os.O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ }
if err := file.Truncate(s.Length); err != nil {
return fmt.Errorf("truncate: %v", err)
}
@@ -126,6 +118,13 @@ func (f *File) wstat(s *lib9p.Stat) error {
}
}
if s.Mode != oldStat.Mode {
+ if file == nil {
+ file, err = os.OpenFile(path.Join(f.fs.rootPath, f.path), os.O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ }
if err := file.Chmod(s.Mode); err != nil {
return fmt.Errorf("chmod: %v", err)
}
@@ -136,7 +135,6 @@ func (f *File) wstat(s *lib9p.Stat) error {
return fmt.Errorf("chtimes: %v", err)
}
}
-
if s.Gid != oldStat.Gid {
group, err := user.LookupGroup(s.Gid)
if err != nil {
@@ -154,12 +152,25 @@ func (f *File) wstat(s *lib9p.Stat) error {
if err != nil {
return fmt.Errorf("convert gid: %v", err)
}
-
+ if file == nil {
+ file, err = os.OpenFile(path.Join(f.fs.rootPath, f.path), os.O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ }
if err := file.Chown(u, g); err != nil {
return fmt.Errorf("chown: %v", err)
}
}
-
+ if s.Name != oldStat.Name {
+ // TODO: check neither Names contains "/"
+ oldpath := path.Join(f.fs.rootPath, path.Dir(f.path), oldStat.Name)
+ newpath := path.Join(f.fs.rootPath, path.Dir(f.path), s.Name)
+ if err := os.Rename(oldpath, newpath); err != nil {
+ return fmt.Errorf("rename: %v", err)
+ }
+ }
return nil
}