From d903c709d3a473437c850de76c9b31c87441a50e Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Wed, 29 Jul 2015 10:39:37 +1000 Subject: [PATCH] Refactored allocation out OutMessage structs. In preparation for allocating them up-front for ReadFile and ReadDir. --- connection.go | 10 ++++---- conversions.go | 62 ++++++++++++++++++-------------------------------- 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/connection.go b/connection.go index d35184b..4f9b4d7 100644 --- a/connection.go +++ b/connection.go @@ -450,15 +450,17 @@ func (c *Connection) Reply(ctx context.Context, opErr error) { } // Send the reply to the kernel, if one is required. - outMsg := c.kernelResponse(m.Header().Unique, op, opErr) - if outMsg != nil { - err := c.writeMessage(outMsg.Bytes()) - c.putOutMessage(outMsg) + outMsg := c.getOutMessage() + noResponse := c.kernelResponse(outMsg, m.Header().Unique, op, opErr) + if !noResponse { + err := c.writeMessage(outMsg.Bytes()) if err != nil && c.errorLogger != nil { c.errorLogger.Printf("writeMessage: %v", err) } } + + c.putOutMessage(outMsg) } // Close the connection. Must not be called until operations that were read diff --git a/conversions.go b/conversions.go index 481fc39..558d1d1 100644 --- a/conversions.go +++ b/conversions.go @@ -387,51 +387,45 @@ func convertInMessage( // Outgoing messages //////////////////////////////////////////////////////////////////////// -// Return the response that should be sent to the kernel, or nil if the op -// requires no response. +// Fill in the response that should be sent to the kernel, or set noResponse if +// the op requires no response. func (c *Connection) kernelResponse( + m *buffer.OutMessage, fuseID uint64, op interface{}, - opErr error) (m *buffer.OutMessage) { - // If the user replied with an error, create a response containing just the - // result header with the error filled in. Otherwise create an appropriate - // response. + opErr error) (noResponse bool) { + h := m.OutHeader() + h.Unique = fuseID + + // Did the user return an error? Otherwise, fill in the rest of the response. if opErr != nil { - m = c.getOutMessage() if errno, ok := opErr.(syscall.Errno); ok { m.OutHeader().Error = -int32(errno) } else { m.OutHeader().Error = -int32(syscall.EIO) } } else { - m = c.kernelResponseForOp(op) - } - - // Fill in the rest of the header, if a response is required. - if m != nil { - h := m.OutHeader() - h.Unique = fuseID - h.Len = uint32(m.Len()) + noResponse = c.kernelResponseForOp(m, op) } + h.Len = uint32(m.Len()) return } // Like kernelResponse, but assumes the user replied with a nil error to the -// op. Returns a nil response if no response is required. +// op. func (c *Connection) kernelResponseForOp( - op interface{}) (m *buffer.OutMessage) { + m *buffer.OutMessage, + op interface{}) (noResponse bool) { // Create the appropriate output message switch o := op.(type) { case *fuseops.LookUpInodeOp: size := fusekernel.EntryOutSize(c.protocol) - m = c.getOutMessage() out := (*fusekernel.EntryOut)(m.Grow(size)) convertChildInodeEntry(&o.Entry, out) case *fuseops.GetInodeAttributesOp: size := fusekernel.AttrOutSize(c.protocol) - m = c.getOutMessage() out := (*fusekernel.AttrOut)(m.Grow(size)) out.AttrValid, out.AttrValidNsec = convertExpirationTime( o.AttributesExpiration) @@ -439,24 +433,21 @@ func (c *Connection) kernelResponseForOp( case *fuseops.SetInodeAttributesOp: size := fusekernel.AttrOutSize(c.protocol) - m = c.getOutMessage() out := (*fusekernel.AttrOut)(m.Grow(size)) out.AttrValid, out.AttrValidNsec = convertExpirationTime( o.AttributesExpiration) convertAttributes(o.Inode, &o.Attributes, &out.Attr) case *fuseops.ForgetInodeOp: - // No response. + noResponse = true case *fuseops.MkDirOp: size := fusekernel.EntryOutSize(c.protocol) - m = c.getOutMessage() out := (*fusekernel.EntryOut)(m.Grow(size)) convertChildInodeEntry(&o.Entry, out) case *fuseops.CreateFileOp: eSize := fusekernel.EntryOutSize(c.protocol) - m = c.getOutMessage() e := (*fusekernel.EntryOut)(m.Grow(eSize)) convertChildInodeEntry(&o.Entry, e) @@ -466,67 +457,58 @@ func (c *Connection) kernelResponseForOp( case *fuseops.CreateSymlinkOp: size := fusekernel.EntryOutSize(c.protocol) - m = c.getOutMessage() out := (*fusekernel.EntryOut)(m.Grow(size)) convertChildInodeEntry(&o.Entry, out) case *fuseops.RenameOp: - m = c.getOutMessage() + // Empty response case *fuseops.RmDirOp: - m = c.getOutMessage() + // Empty response case *fuseops.UnlinkOp: - m = c.getOutMessage() + // Empty response case *fuseops.OpenDirOp: - m = c.getOutMessage() out := (*fusekernel.OpenOut)(m.Grow(unsafe.Sizeof(fusekernel.OpenOut{}))) out.Fh = uint64(o.Handle) case *fuseops.ReadDirOp: - m = c.getOutMessage() m.Append(o.Dst[:o.BytesRead]) case *fuseops.ReleaseDirHandleOp: - m = c.getOutMessage() + // Empty response case *fuseops.OpenFileOp: - m = c.getOutMessage() out := (*fusekernel.OpenOut)(m.Grow(unsafe.Sizeof(fusekernel.OpenOut{}))) out.Fh = uint64(o.Handle) case *fuseops.ReadFileOp: - m = c.getOutMessage() m.Append(o.Dst[:o.BytesRead]) case *fuseops.WriteFileOp: - m = c.getOutMessage() out := (*fusekernel.WriteOut)(m.Grow(unsafe.Sizeof(fusekernel.WriteOut{}))) out.Size = uint32(len(o.Data)) case *fuseops.SyncFileOp: - m = c.getOutMessage() + // Empty response case *fuseops.FlushFileOp: - m = c.getOutMessage() + // Empty response case *fuseops.ReleaseFileHandleOp: - m = c.getOutMessage() + // Empty response case *fuseops.ReadSymlinkOp: - m = c.getOutMessage() m.AppendString(o.Target) case *statFSOp: - m = c.getOutMessage() m.Grow(unsafe.Sizeof(fusekernel.StatfsOut{})) case *interruptOp: - // No response. + noResponse = true case *initOp: - m = c.getOutMessage() out := (*fusekernel.InitOut)(m.Grow(unsafe.Sizeof(fusekernel.InitOut{}))) out.Major = o.Library.Major