summaryrefslogtreecommitdiffhomepage
path: root/pkg/p9
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/p9')
-rw-r--r--pkg/p9/client.go4
-rw-r--r--pkg/p9/file.go16
-rw-r--r--pkg/p9/handlers.go2
-rw-r--r--pkg/p9/transport_flipcall.go10
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.