diff options
-rw-r--r-- | pkg/p9/handlers.go | 81 | ||||
-rw-r--r-- | pkg/p9/server.go | 14 |
2 files changed, 44 insertions, 51 deletions
diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index abd237f46..81ceb37c5 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -296,25 +296,6 @@ func (t *Tlopen) handle(cs *connState) message { } defer ref.DecRef() - ref.openedMu.Lock() - defer ref.openedMu.Unlock() - - // Has it been opened already? - if ref.opened || !CanOpen(ref.mode) { - return newErr(syscall.EINVAL) - } - - if ref.mode.IsDir() { - // Directory must be opened ReadOnly. - if t.Flags&OpenFlagsModeMask != ReadOnly { - return newErr(syscall.EISDIR) - } - // Directory not truncatable. - if t.Flags&OpenTruncate != 0 { - return newErr(syscall.EISDIR) - } - } - var ( qid QID ioUnit uint32 @@ -326,6 +307,22 @@ func (t *Tlopen) handle(cs *connState) message { return syscall.EINVAL } + // Has it been opened already? + if ref.opened || !CanOpen(ref.mode) { + return syscall.EINVAL + } + + if ref.mode.IsDir() { + // Directory must be opened ReadOnly. + if t.Flags&OpenFlagsModeMask != ReadOnly { + return syscall.EISDIR + } + // Directory not truncatable. + if t.Flags&OpenTruncate != 0 { + return syscall.EISDIR + } + } + osFile, qid, ioUnit, err = ref.file.Open(t.Flags) return err }); err != nil { @@ -366,7 +363,7 @@ func (t *Tlcreate) do(cs *connState, uid UID) (*Rlcreate, error) { } // Not allowed on open directories. - if _, opened := ref.OpenFlags(); opened { + if ref.opened { return syscall.EINVAL } @@ -437,7 +434,7 @@ func (t *Tsymlink) do(cs *connState, uid UID) (*Rsymlink, error) { } // Not allowed on open directories. - if _, opened := ref.OpenFlags(); opened { + if ref.opened { return syscall.EINVAL } @@ -476,7 +473,7 @@ func (t *Tlink) handle(cs *connState) message { } // Not allowed on open directories. - if _, opened := ref.OpenFlags(); opened { + if ref.opened { return syscall.EINVAL } @@ -518,7 +515,7 @@ func (t *Trenameat) handle(cs *connState) message { } // Not allowed on open directories. - if _, opened := ref.OpenFlags(); opened { + if ref.opened { return syscall.EINVAL } @@ -561,7 +558,7 @@ func (t *Tunlinkat) handle(cs *connState) message { } // Not allowed on open directories. - if _, opened := ref.OpenFlags(); opened { + if ref.opened { return syscall.EINVAL } @@ -701,13 +698,12 @@ func (t *Tread) handle(cs *connState) message { ) if err := ref.safelyRead(func() (err error) { // Has it been opened already? - openFlags, opened := ref.OpenFlags() - if !opened { + if !ref.opened { return syscall.EINVAL } // Can it be read? Check permissions. - if openFlags&OpenFlagsModeMask == WriteOnly { + if ref.openFlags&OpenFlagsModeMask == WriteOnly { return syscall.EPERM } @@ -731,13 +727,12 @@ func (t *Twrite) handle(cs *connState) message { var n int if err := ref.safelyRead(func() (err error) { // Has it been opened already? - openFlags, opened := ref.OpenFlags() - if !opened { + if !ref.opened { return syscall.EINVAL } // Can it be written? Check permissions. - if openFlags&OpenFlagsModeMask == ReadOnly { + if ref.openFlags&OpenFlagsModeMask == ReadOnly { return syscall.EPERM } @@ -778,7 +773,7 @@ func (t *Tmknod) do(cs *connState, uid UID) (*Rmknod, error) { } // Not allowed on open directories. - if _, opened := ref.OpenFlags(); opened { + if ref.opened { return syscall.EINVAL } @@ -820,7 +815,7 @@ func (t *Tmkdir) do(cs *connState, uid UID) (*Rmkdir, error) { } // Not allowed on open directories. - if _, opened := ref.OpenFlags(); opened { + if ref.opened { return syscall.EINVAL } @@ -898,13 +893,12 @@ func (t *Tallocate) handle(cs *connState) message { if err := ref.safelyWrite(func() error { // Has it been opened already? - openFlags, opened := ref.OpenFlags() - if !opened { + if !ref.opened { return syscall.EINVAL } // Can it be written? Check permissions. - if openFlags&OpenFlagsModeMask == ReadOnly { + if ref.openFlags&OpenFlagsModeMask == ReadOnly { return syscall.EBADF } @@ -1049,8 +1043,8 @@ func (t *Treaddir) handle(cs *connState) message { return syscall.EINVAL } - // Has it been opened already? - if _, opened := ref.OpenFlags(); !opened { + // Has it been opened yet? + if !ref.opened { return syscall.EINVAL } @@ -1076,8 +1070,8 @@ func (t *Tfsync) handle(cs *connState) message { defer ref.DecRef() if err := ref.safelyRead(func() (err error) { - // Has it been opened already? - if _, opened := ref.OpenFlags(); !opened { + // Has it been opened yet? + if !ref.opened { return syscall.EINVAL } @@ -1185,8 +1179,13 @@ func doWalk(cs *connState, ref *fidRef, names []string, getattr bool) (qids []QI } // Has it been opened already? - if _, opened := ref.OpenFlags(); opened { - err = syscall.EBUSY + err = ref.safelyRead(func() (err error) { + if ref.opened { + return syscall.EBUSY + } + return nil + }) + if err != nil { return } diff --git a/pkg/p9/server.go b/pkg/p9/server.go index 3736f12a3..8c5c434fd 100644 --- a/pkg/p9/server.go +++ b/pkg/p9/server.go @@ -134,12 +134,11 @@ type fidRef struct { // The node above will be closed only when refs reaches zero. refs int64 - // openedMu protects opened and openFlags. - openedMu sync.Mutex - // opened indicates whether this has been opened already. // // This is updated in handlers.go. + // + // opened is protected by pathNode.opMu or renameMu (for write). opened bool // mode is the fidRef's mode from the walk. Only the type bits are @@ -151,6 +150,8 @@ type fidRef struct { // openFlags is the mode used in the open. // // This is updated in handlers.go. + // + // openFlags is protected by pathNode.opMu or renameMu (for write). openFlags OpenFlags // pathNode is the current pathNode for this FID. @@ -177,13 +178,6 @@ type fidRef struct { deleted uint32 } -// OpenFlags returns the flags the file was opened with and true iff the fid was opened previously. -func (f *fidRef) OpenFlags() (OpenFlags, bool) { - f.openedMu.Lock() - defer f.openedMu.Unlock() - return f.openFlags, f.opened -} - // IncRef increases the references on a fid. func (f *fidRef) IncRef() { atomic.AddInt64(&f.refs, 1) |