summaryrefslogtreecommitdiffhomepage
path: root/pkg/p9
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/p9')
-rw-r--r--pkg/p9/client.go23
-rw-r--r--pkg/p9/file.go2
-rw-r--r--pkg/p9/p9.go39
-rw-r--r--pkg/p9/server.go8
-rw-r--r--pkg/p9/transport_flipcall.go24
5 files changed, 54 insertions, 42 deletions
diff --git a/pkg/p9/client.go b/pkg/p9/client.go
index 2412aa5e1..221516c6c 100644
--- a/pkg/p9/client.go
+++ b/pkg/p9/client.go
@@ -505,12 +505,27 @@ func (c *Client) sendRecvChannel(t message, r message) error {
ch.active = false
c.channelsMu.Unlock()
c.channelsWg.Done()
- return err
+ // Map all transport errors to EIO, but ensure that the real error
+ // is logged.
+ log.Warningf("p9.Client.sendRecvChannel: flipcall.Endpoint.Connect: %v", err)
+ return syscall.EIO
}
}
- // Send the message.
- err := ch.sendRecv(c, t, r)
+ // Send the request and receive the server's response.
+ rsz, err := ch.send(t)
+ if err != nil {
+ // See above.
+ c.channelsMu.Lock()
+ ch.active = false
+ c.channelsMu.Unlock()
+ c.channelsWg.Done()
+ log.Warningf("p9.Client.sendRecvChannel: p9.channel.send: %v", err)
+ return syscall.EIO
+ }
+
+ // Parse the server's response.
+ _, retErr := ch.recv(r, rsz)
// Release the channel.
c.channelsMu.Lock()
@@ -523,7 +538,7 @@ func (c *Client) sendRecvChannel(t message, r message) error {
c.channelsMu.Unlock()
c.channelsWg.Done()
- return err
+ return retErr
}
// Version returns the negotiated 9P2000.L.Google version number.
diff --git a/pkg/p9/file.go b/pkg/p9/file.go
index 907445e15..96d1f2a8e 100644
--- a/pkg/p9/file.go
+++ b/pkg/p9/file.go
@@ -116,7 +116,7 @@ type File interface {
// N.B. The server must resolve any lazy paths when open is called.
// After this point, read and write may be called on files with no
// deletion check, so resolving in the data path is not viable.
- Open(mode OpenFlags) (*fd.FD, QID, uint32, error)
+ Open(flags OpenFlags) (*fd.FD, QID, uint32, error)
// Read reads from this file. Open must be called first.
//
diff --git a/pkg/p9/p9.go b/pkg/p9/p9.go
index 25530adca..415200d60 100644
--- a/pkg/p9/p9.go
+++ b/pkg/p9/p9.go
@@ -32,18 +32,22 @@ import (
type OpenFlags uint32
const (
- // ReadOnly is a Topen and Tcreate flag indicating read-only mode.
+ // ReadOnly is a Tlopen and Tlcreate flag indicating read-only mode.
ReadOnly OpenFlags = 0
- // WriteOnly is a Topen and Tcreate flag indicating write-only mode.
+ // WriteOnly is a Tlopen and Tlcreate flag indicating write-only mode.
WriteOnly OpenFlags = 1
- // ReadWrite is a Topen flag indicates read-write mode.
+ // ReadWrite is a Tlopen flag indicates read-write mode.
ReadWrite OpenFlags = 2
// OpenFlagsModeMask is a mask of valid OpenFlags mode bits.
OpenFlagsModeMask OpenFlags = 3
+ // OpenTruncate is a Tlopen flag indicating that the opened file should be
+ // truncated.
+ OpenTruncate OpenFlags = 01000
+
// OpenFlagsIgnoreMask is a list of OpenFlags mode bits that are ignored for Tlopen.
// Note that syscall.O_LARGEFILE is set to zero, use value from Linux fcntl.h.
OpenFlagsIgnoreMask OpenFlags = syscall.O_DIRECTORY | syscall.O_NOATIME | 0100000
@@ -71,25 +75,32 @@ const (
// OSFlags converts a p9.OpenFlags to an int compatible with open(2).
func (o OpenFlags) OSFlags() int {
- return int(o & OpenFlagsModeMask)
+ // "flags contains Linux open(2) flags bits" - 9P2000.L
+ return int(o)
}
// String implements fmt.Stringer.
func (o OpenFlags) String() string {
- switch o {
+ var buf strings.Builder
+ switch mode := o & OpenFlagsModeMask; mode {
case ReadOnly:
- return "ReadOnly"
+ buf.WriteString("ReadOnly")
case WriteOnly:
- return "WriteOnly"
+ buf.WriteString("WriteOnly")
case ReadWrite:
- return "ReadWrite"
- case OpenFlagsModeMask:
- return "OpenFlagsModeMask"
- case OpenFlagsIgnoreMask:
- return "OpenFlagsIgnoreMask"
+ buf.WriteString("ReadWrite")
default:
- return "UNDEFINED"
+ fmt.Fprintf(&buf, "%#o", mode)
+ }
+ otherFlags := o &^ OpenFlagsModeMask
+ if otherFlags&OpenTruncate != 0 {
+ buf.WriteString("|OpenTruncate")
+ otherFlags &^= OpenTruncate
+ }
+ if otherFlags != 0 {
+ fmt.Fprintf(&buf, "|%#o", otherFlags)
}
+ return buf.String()
}
// Tag is a message tag.
@@ -814,7 +825,7 @@ func StatToAttr(s *syscall.Stat_t, req AttrMask) (Attr, AttrMask) {
attr.Mode = FileMode(s.Mode)
}
if req.NLink {
- attr.NLink = s.Nlink
+ attr.NLink = uint64(s.Nlink)
}
if req.UID {
attr.UID = UID(s.Uid)
diff --git a/pkg/p9/server.go b/pkg/p9/server.go
index 69c886a5d..40b8fa023 100644
--- a/pkg/p9/server.go
+++ b/pkg/p9/server.go
@@ -452,7 +452,13 @@ func (cs *connState) initializeChannels() (err error) {
cs.channelWg.Add(1)
go func() { // S/R-SAFE: Server side.
defer cs.channelWg.Done()
- res.service(cs)
+ if err := res.service(cs); err != nil {
+ // Don't log flipcall.ShutdownErrors, which we expect to be
+ // returned during server shutdown.
+ if _, ok := err.(flipcall.ShutdownError); !ok {
+ log.Warningf("p9.channel.service: %v", err)
+ }
+ }
}()
}
diff --git a/pkg/p9/transport_flipcall.go b/pkg/p9/transport_flipcall.go
index 7cdf4ecc3..233f825e3 100644
--- a/pkg/p9/transport_flipcall.go
+++ b/pkg/p9/transport_flipcall.go
@@ -132,7 +132,7 @@ func (ch *channel) send(m message) (uint32, error) {
if filer, ok := m.(filer); ok {
if f := filer.FilePayload(); f != nil {
if err := ch.fds.SendFD(f.FD()); err != nil {
- return 0, syscall.EIO // Map everything to EIO.
+ return 0, err
}
f.Close() // Per sendRecvLegacy.
sentFD = true // To mark below.
@@ -162,15 +162,7 @@ func (ch *channel) send(m message) (uint32, error) {
}
// Perform the one-shot communication.
- n, err := ch.data.SendRecv(ssz)
- if err != nil {
- if n > 0 {
- return n, nil
- }
- return 0, syscall.EIO // See above.
- }
-
- return n, nil
+ return ch.data.SendRecv(ssz)
}
// recv decodes a message that exists on the channel.
@@ -249,15 +241,3 @@ func (ch *channel) recv(r message, rsz uint32) (message, error) {
return r, nil
}
-
-// sendRecv sends the given message over the channel.
-//
-// This is used by the client.
-func (ch *channel) sendRecv(c *Client, m, r message) error {
- rsz, err := ch.send(m)
- if err != nil {
- return err
- }
- _, err = ch.recv(r, rsz)
- return err
-}