16561: Handle implicit port number in ws:// and wss:// urls.
[arvados.git] / lib / mount / fs.go
index 774948f574607b04f8548837720e6ba5c06c7c2f..3c2e628d0115e361f58150f589060ee14bc57f1b 100644 (file)
@@ -5,6 +5,7 @@
 package mount
 
 import (
+       "errors"
        "io"
        "log"
        "os"
@@ -36,7 +37,7 @@ type keepFS struct {
        root   arvados.CustomFileSystem
        open   map[uint64]*sharedFile
        lastFH uint64
-       sync.Mutex
+       sync.RWMutex
 
        // If non-nil, this channel will be closed by Init() to notify
        // other goroutines that the mount is ready.
@@ -62,8 +63,8 @@ func (fs *keepFS) newFH(f arvados.File) uint64 {
 }
 
 func (fs *keepFS) lookupFH(fh uint64) *sharedFile {
-       fs.Lock()
-       defer fs.Unlock()
+       fs.RLock()
+       defer fs.RUnlock()
        return fs.open[fh]
 }
 
@@ -121,23 +122,25 @@ func (fs *keepFS) Utimens(path string, tmsp []fuse.Timespec) int {
 }
 
 func (fs *keepFS) errCode(err error) int {
-       if os.IsNotExist(err) {
+       if err == nil {
+               return 0
+       }
+       if errors.Is(err, os.ErrNotExist) {
                return -fuse.ENOENT
        }
-       switch err {
-       case os.ErrExist:
+       if errors.Is(err, os.ErrExist) {
                return -fuse.EEXIST
-       case arvados.ErrInvalidArgument:
+       }
+       if errors.Is(err, arvados.ErrInvalidArgument) {
                return -fuse.EINVAL
-       case arvados.ErrInvalidOperation:
+       }
+       if errors.Is(err, arvados.ErrInvalidOperation) {
                return -fuse.ENOSYS
-       case arvados.ErrDirectoryNotEmpty:
+       }
+       if errors.Is(err, arvados.ErrDirectoryNotEmpty) {
                return -fuse.ENOTEMPTY
-       case nil:
-               return 0
-       default:
-               return -fuse.EIO
        }
+       return -fuse.EIO
 }
 
 func (fs *keepFS) Mkdir(path string, mode uint32) int {
@@ -252,11 +255,18 @@ func (fs *keepFS) Chmod(path string, mode uint32) (errc int) {
        }
        if fi, err := fs.root.Stat(path); err != nil {
                return fs.errCode(err)
-       } else if mode & ^uint32(fuse.S_IFREG|fuse.S_IFDIR|0777) != 0 || (fi.Mode()&os.ModeDir != 0) != (mode&fuse.S_IFDIR != 0) {
+       } else if mode & ^uint32(fuse.S_IFREG|fuse.S_IFDIR|0777) != 0 {
+               // Refuse to set mode bits other than
+               // regfile/dir/perms
+               return -fuse.ENOSYS
+       } else if (fi.Mode()&os.ModeDir != 0) != (mode&fuse.S_IFDIR != 0) {
+               // Refuse to transform a regular file to a dir, or
+               // vice versa
                return -fuse.ENOSYS
-       } else {
-               return 0
        }
+       // As long as the change isn't nonsense, chmod is a no-op,
+       // because we don't save permission bits.
+       return 0
 }
 
 func (fs *keepFS) fillStat(stat *fuse.Stat_t, fi os.FileInfo) {