// Copyright 2015 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package fuse import ( "fmt" "reflect" "strings" "github.com/jacobsa/fuse/fuseops" ) // Decide on the name of the given op. func opName(op interface{}) string { // We expect all ops to be pointers. t := reflect.TypeOf(op).Elem() // Strip the "Op" from "FooOp". return strings.TrimSuffix(t.Name(), "Op") } func describeRequest(op interface{}) (s string) { v := reflect.ValueOf(op).Elem() // We will set up a comma-separated list of components. var components []string addComponent := func(format string, v ...interface{}) { components = append(components, fmt.Sprintf(format, v...)) } // Include an inode number, if available. if f := v.FieldByName("Inode"); f.IsValid() { addComponent("inode %v", f.Interface()) } // Handle special cases. switch typed := op.(type) { case *interruptOp: addComponent("fuseid 0x%08x", typed.FuseID) case *fuseops.ReadFileOp: addComponent("handle %d", typed.Handle) addComponent("offset %d", typed.Offset) addComponent("%d bytes", len(typed.Dst)) case *fuseops.WriteFileOp: addComponent("handle %d", typed.Handle) addComponent("offset %d", typed.Offset) addComponent("%d bytes", len(typed.Data)) } // Use just the name if there is no extra info. if len(components) == 0 { return opName(op) } // Otherwise, include the extra info. return fmt.Sprintf("%s (%s)", opName(op), strings.Join(components, ", ")) }