Skip to content

Commit 9e256e6

Browse files
committed
sysx/xattr: fix getxattrAll
The current implementation is suboptimal for two reasons: * the initial buffer size of 5 bytes makes no sense (my guess someone forgot to change it back to a sane value after the retry logic testing); * it never gets the real buffer size, resulting in extra iterations (5 -> 10 -> 20 -> ...). This commit * sets the initial size to 128; * uses the logic to get the real size in case we get ERANGE Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 26c1120 commit 9e256e6

1 file changed

Lines changed: 12 additions & 18 deletions

File tree

sysx/xattr.go

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package sysx
2020

2121
import (
2222
"bytes"
23-
"syscall"
2423

2524
"golang.org/x/sys/unix"
2625
)
@@ -66,7 +65,7 @@ func LGetxattr(path, attr string) ([]byte, error) {
6665
return getxattrAll(path, attr, unix.Lgetxattr)
6766
}
6867

69-
const defaultXattrBufferSize = 5
68+
const defaultXattrBufferSize = 128
7069

7170
type listxattrFunc func(path string, dest []byte) (int, error)
7271

@@ -102,24 +101,19 @@ func listxattrAll(path string, listFunc listxattrFunc) ([]string, error) {
102101
type getxattrFunc func(string, string, []byte) (int, error)
103102

104103
func getxattrAll(path, attr string, getFunc getxattrFunc) ([]byte, error) {
105-
p := make([]byte, defaultXattrBufferSize)
106-
for {
107-
n, err := getFunc(path, attr, p)
104+
buf := make([]byte, defaultXattrBufferSize)
105+
n, err := getFunc(path, attr, buf)
106+
for err == unix.ERANGE {
107+
// Buffer too small, use zero-sized buffer to get the actual size
108+
n, err = getFunc(path, attr, []byte{})
108109
if err != nil {
109-
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERANGE {
110-
p = make([]byte, len(p)*2) // this can't be ideal.
111-
continue // try again!
112-
}
113-
114110
return nil, err
115111
}
116-
117-
// realloc to correct size and repeat
118-
if n > len(p) {
119-
p = make([]byte, n)
120-
continue
121-
}
122-
123-
return p[:n], nil
112+
buf = make([]byte, n)
113+
n, err = getFunc(path, attr, buf)
114+
}
115+
if err != nil {
116+
return nil, err
124117
}
118+
return buf[:n], nil
125119
}

0 commit comments

Comments
 (0)