diff options
Diffstat (limited to 'pkg/p9')
-rw-r--r-- | pkg/p9/client.go | 4 | ||||
-rw-r--r-- | pkg/p9/file.go | 16 | ||||
-rw-r--r-- | pkg/p9/handlers.go | 2 | ||||
-rw-r--r-- | pkg/p9/transport_flipcall.go | 10 |
4 files changed, 19 insertions, 13 deletions
diff --git a/pkg/p9/client.go b/pkg/p9/client.go index 764f1f970..d618da820 100644 --- a/pkg/p9/client.go +++ b/pkg/p9/client.go @@ -115,7 +115,7 @@ type Client struct { // channels is the set of all initialized channels. channels []*channel - // availableChannels is a FIFO of inactive channels. + // availableChannels is a LIFO of inactive channels. availableChannels []*channel // -- below corresponds to sendRecvLegacy -- @@ -528,7 +528,7 @@ func (c *Client) sendRecvChannel(t message, r message) error { } // Send the request and receive the server's response. - rsz, err := ch.send(t) + rsz, err := ch.send(t, false /* isServer */) if err != nil { // See above. c.channelsMu.Lock() diff --git a/pkg/p9/file.go b/pkg/p9/file.go index 97e0231d6..8d6af2d6b 100644 --- a/pkg/p9/file.go +++ b/pkg/p9/file.go @@ -325,6 +325,12 @@ func (*DisallowServerCalls) Renamed(File, string) { func DefaultMultiGetAttr(start File, names []string) ([]FullStat, error) { stats := make([]FullStat, 0, len(names)) parent := start + closeParent := func() { + if parent != start { + _ = parent.Close() + } + } + defer closeParent() mask := AttrMaskAll() for i, name := range names { if len(name) == 0 && i == 0 { @@ -340,15 +346,14 @@ func DefaultMultiGetAttr(start File, names []string) ([]FullStat, error) { continue } qids, child, valid, attr, err := parent.WalkGetAttr([]string{name}) - if parent != start { - _ = parent.Close() - } if err != nil { if errors.Is(err, unix.ENOENT) { return stats, nil } return nil, err } + closeParent() + parent = child stats = append(stats, FullStat{ QID: qids[0], Valid: valid, @@ -357,13 +362,8 @@ func DefaultMultiGetAttr(start File, names []string) ([]FullStat, error) { if attr.Mode.FileType() != ModeDirectory { // Doesn't need to continue if entry is not a dir. Including symlinks // that cannot be followed. - _ = child.Close() break } - parent = child - } - if parent != start { - _ = parent.Close() } return stats, nil } diff --git a/pkg/p9/handlers.go b/pkg/p9/handlers.go index 161b451cc..a8f8a9d03 100644 --- a/pkg/p9/handlers.go +++ b/pkg/p9/handlers.go @@ -45,6 +45,8 @@ func ExtractErrno(err error) unix.Errno { // Attempt to unwrap. switch e := err.(type) { + case *errors.Error: + return unix.Errno(e.Errno()) case unix.Errno: return e case *os.PathError: diff --git a/pkg/p9/transport_flipcall.go b/pkg/p9/transport_flipcall.go index 802254a90..69a9f2537 100644 --- a/pkg/p9/transport_flipcall.go +++ b/pkg/p9/transport_flipcall.go @@ -85,7 +85,7 @@ func (ch *channel) service(cs *connState) error { } r := cs.handle(m) msgRegistry.put(m) - rsz, err = ch.send(r) + rsz, err = ch.send(r, true /* isServer */) if err != nil { return err } @@ -122,7 +122,7 @@ func (ch *channel) Close() error { // // The return value is the size of the received response. Not that in the // server case, this is the size of the next request. -func (ch *channel) send(m message) (uint32, error) { +func (ch *channel) send(m message, isServer bool) (uint32, error) { if log.IsLogging(log.Debug) { log.Debugf("send [channel @%p] %s", ch, m.String()) } @@ -162,7 +162,11 @@ func (ch *channel) send(m message) (uint32, error) { } // Perform the one-shot communication. - return ch.data.SendRecv(ssz) + if isServer { + return ch.data.SendRecv(ssz) + } + // RPCs are expected to return quickly rather than block. + return ch.data.SendRecvFast(ssz) } // recv decodes a message that exists on the channel. |