Avoid calling Logf on the hot path when logging is disabled.
The call to commonOp.Logf in sendBazilfuseResponse is extremely hot for allocations, presumably because it needs to allocate an argument slice. It is normally not needed at all, so why pay for it?geesefs-0-30-9
parent
4b1e4b55f9
commit
f004d3ff4a
|
@ -50,6 +50,8 @@ type Connection struct {
|
|||
|
||||
// Responsibility for closing the wrapped connection is transferred to the
|
||||
// result. You must call c.close() eventually.
|
||||
//
|
||||
// The loggers may be nil.
|
||||
func newConnection(
|
||||
parentCtx context.Context,
|
||||
debugLogger *log.Logger,
|
||||
|
@ -73,6 +75,10 @@ func (c *Connection) debugLog(
|
|||
calldepth int,
|
||||
format string,
|
||||
v ...interface{}) {
|
||||
if c.debugLogger == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Get file:line info.
|
||||
var file string
|
||||
var line int
|
||||
|
@ -239,8 +245,11 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
|
|||
// Set up op dependencies.
|
||||
opCtx := c.beginOp(bfReq)
|
||||
|
||||
debugLogForOp := func(calldepth int, format string, v ...interface{}) {
|
||||
c.debugLog(opID, calldepth+1, format, v...)
|
||||
var debugLogForOp func(int, string, ...interface{})
|
||||
if c.debugLogger != nil {
|
||||
debugLogForOp = func(calldepth int, format string, v ...interface{}) {
|
||||
c.debugLog(opID, calldepth+1, format, v...)
|
||||
}
|
||||
}
|
||||
|
||||
finished := func(err error) { c.finishOp(bfReq) }
|
||||
|
|
|
@ -49,9 +49,13 @@ type commonOp struct {
|
|||
|
||||
// A function that can be used to log debug information about the op. The
|
||||
// first argument is a call depth.
|
||||
//
|
||||
// May be nil.
|
||||
debugLog func(int, string, ...interface{})
|
||||
|
||||
// A logger to be used for logging exceptional errors.
|
||||
//
|
||||
// May be nil.
|
||||
errorLogger *log.Logger
|
||||
|
||||
// A function that is invoked with the error given to Respond, for use in
|
||||
|
@ -116,6 +120,10 @@ func (o *commonOp) Context() context.Context {
|
|||
}
|
||||
|
||||
func (o *commonOp) Logf(format string, v ...interface{}) {
|
||||
if o.debugLog == nil {
|
||||
return
|
||||
}
|
||||
|
||||
const calldepth = 2
|
||||
o.debugLog(calldepth, format, v...)
|
||||
}
|
||||
|
@ -131,15 +139,19 @@ func (o *commonOp) Respond(err error) {
|
|||
}
|
||||
|
||||
// Log the error.
|
||||
o.Logf(
|
||||
"-> (%s) error: %v",
|
||||
o.op.ShortDesc(),
|
||||
err)
|
||||
if o.debugLog != nil {
|
||||
o.Logf(
|
||||
"-> (%s) error: %v",
|
||||
o.op.ShortDesc(),
|
||||
err)
|
||||
}
|
||||
|
||||
o.errorLogger.Printf(
|
||||
"(%s) error: %v",
|
||||
o.op.ShortDesc(),
|
||||
err)
|
||||
if o.errorLogger != nil {
|
||||
o.errorLogger.Printf(
|
||||
"(%s) error: %v",
|
||||
o.op.ShortDesc(),
|
||||
err)
|
||||
}
|
||||
|
||||
// Send a response to the kernel.
|
||||
o.bazilReq.RespondError(err)
|
||||
|
@ -157,11 +169,15 @@ func (o *commonOp) sendBazilfuseResponse(resp interface{}) {
|
|||
// Special case: handle successful ops with no response struct.
|
||||
if resp == nil {
|
||||
o.Logf("-> (%s) OK", o.op.ShortDesc())
|
||||
|
||||
respond.Call([]reflect.Value{})
|
||||
return
|
||||
}
|
||||
|
||||
// Otherwise, send the response struct to the kernel.
|
||||
o.Logf("-> %v", resp)
|
||||
if o.debugLog != nil {
|
||||
o.Logf("-> %v", resp)
|
||||
}
|
||||
|
||||
respond.Call([]reflect.Value{reflect.ValueOf(resp)})
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import (
|
|||
//
|
||||
// It is guaranteed that o != nil. If the op is unknown, a special unexported
|
||||
// type will be used.
|
||||
//
|
||||
// The debug logging function and error logger may be nil.
|
||||
func Convert(
|
||||
opCtx context.Context,
|
||||
r bazilfuse.Request,
|
||||
|
|
|
@ -16,7 +16,6 @@ package fuse
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"runtime"
|
||||
|
||||
|
@ -193,12 +192,6 @@ func Mount(
|
|||
dir string,
|
||||
server Server,
|
||||
config *MountConfig) (mfs *MountedFileSystem, err error) {
|
||||
// Arrange for a non-nil debug logger.
|
||||
debugLogger := config.DebugLogger
|
||||
if debugLogger == nil {
|
||||
debugLogger = log.New(ioutil.Discard, "", 0)
|
||||
}
|
||||
|
||||
// Initialize the struct.
|
||||
mfs = &MountedFileSystem{
|
||||
dir: dir,
|
||||
|
@ -206,7 +199,6 @@ func Mount(
|
|||
}
|
||||
|
||||
// Open a bazilfuse connection.
|
||||
debugLogger.Println("Opening a bazilfuse connection.")
|
||||
bfConn, err := bazilfuse.Mount(mfs.dir, config.bazilfuseOptions()...)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("bazilfuse.Mount: %v", err)
|
||||
|
@ -219,17 +211,11 @@ func Mount(
|
|||
opContext = context.Background()
|
||||
}
|
||||
|
||||
// Create a /dev/null error logger if necessary.
|
||||
errorLogger := config.ErrorLogger
|
||||
if errorLogger == nil {
|
||||
errorLogger = log.New(ioutil.Discard, "", 0)
|
||||
}
|
||||
|
||||
// Create our own Connection object wrapping it.
|
||||
connection, err := newConnection(
|
||||
opContext,
|
||||
debugLogger,
|
||||
errorLogger,
|
||||
config.DebugLogger,
|
||||
config.ErrorLogger,
|
||||
bfConn)
|
||||
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue