Commit 41df6ec8 authored by Jakob Unterwurzacher's avatar Jakob Unterwurzacher Committed by Han-Wen Nienhuys

fuse: improve SETXATTR debug logging

Set the operationHandlers[op].DecodeIn function and
add xattr name parsing.

SETXATTR is special because it is the only opcode that
takes a file name (the xattr name) and a binary blob
(the xattr value). This was not supported by the
file name parsing code:
* setting FileNames = 1 would lump the xattr name
  and value together and truncates the last byte
* setting FileNames = 2 truncated the last xattr
  value byte.

This was solved by adding a special-case to parse(),
which seemed less ugly than adding a special-case
InputDebug(), or leaving the truncation as-is.

Before:
  2018/05/01 16:47:39 Dispatch 6: SETXATTR, NodeId: 3.  12 bytes
After:
  2018/05/01 16:48:36 Dispatch 6: SETXATTR, NodeId: 3. data: {sz 3 f0} names: [user.foo] 12 bytes

The change only affects debug output as doSetXAttr() does its
own bytes.SplitN(). The parsed filename *could* also be used in
doSetXAttr(), but the code seems clearer as-is.
parent 23f81674
......@@ -608,6 +608,7 @@ func init() {
for op, f := range map[int32]castPointerFunc{
_OP_FLUSH: func(ptr unsafe.Pointer) interface{} { return (*FlushIn)(ptr) },
_OP_GETATTR: func(ptr unsafe.Pointer) interface{} { return (*GetAttrIn)(ptr) },
_OP_SETXATTR: func(ptr unsafe.Pointer) interface{} { return (*SetXAttrIn)(ptr) },
_OP_GETXATTR: func(ptr unsafe.Pointer) interface{} { return (*GetXAttrIn)(ptr) },
_OP_LISTXATTR: func(ptr unsafe.Pointer) interface{} { return (*GetXAttrIn)(ptr) },
_OP_SETATTR: func(ptr unsafe.Pointer) interface{} { return (*SetAttrIn)(ptr) },
......@@ -635,6 +636,7 @@ func init() {
// File name args.
for op, count := range map[int32]int{
_OP_CREATE: 1,
_OP_SETXATTR: 1,
_OP_GETXATTR: 1,
_OP_LINK: 1,
_OP_LOOKUP: 1,
......
......@@ -167,7 +167,12 @@ func (r *request) parse() {
count := r.handler.FileNames
if count > 0 {
if count == 1 {
if count == 1 && r.inHeader.Opcode == _OP_SETXATTR {
// SETXATTR is special: the only opcode with a file name AND a
// binary argument.
splits := bytes.SplitN(r.arg, []byte{0}, 2)
r.filenames = []string{string(splits[0])}
} else if count == 1 {
r.filenames = []string{string(r.arg[:len(r.arg)-1])}
} else {
names := bytes.SplitN(r.arg[:len(r.arg)-1], []byte{0}, count)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment