From 14045511d3d91f36845a138359718c0fe7dff21c Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Mon, 2 Feb 2026 22:18:25 +0100 Subject: Use user-provided Listxattr buffer size This huge buffer showed up big time in ./profiling/ls.bash and caused a 2x LS benchmark slowdown. Instead of the fixed-size buffer, use the buffer size hint the user has provided us. We return inaccurate (larger than actual, which should be safe) numbers when the user has provided no buffer (size probe). --- internal/fusefrontend_reverse/node_xattr.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'internal/fusefrontend_reverse/node_xattr.go') diff --git a/internal/fusefrontend_reverse/node_xattr.go b/internal/fusefrontend_reverse/node_xattr.go index f22764a..9e99cfa 100644 --- a/internal/fusefrontend_reverse/node_xattr.go +++ b/internal/fusefrontend_reverse/node_xattr.go @@ -7,6 +7,7 @@ import ( "syscall" "github.com/rfjakob/gocryptfs/v2/internal/pathiv" + "github.com/rfjakob/gocryptfs/v2/internal/syscallcompat" ) // We store encrypted xattrs under this prefix plus the base64-encoded @@ -65,10 +66,18 @@ func (n *Node) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errn if rn.args.NoXattr { return 0, 0 } - pNames, errno := n.listXAttr() + // Can use dest as a temporary buffer + sz, errno := n.listXAttr(dest) if errno != 0 { return 0, errno } + // If dest empty, return the required size + if len(dest) == 0 { + // Asssume ciphertext expansion by a factor of 2 + // TODO: double-check max expansion factor + return uint32(sz * 2), 0 + } + pNames := syscallcompat.ParseListxattrBlob(dest[:sz]) var buf bytes.Buffer for _, pName := range pNames { // ACLs are passed through without encryption -- cgit v1.2.3