Commit 5ee141ce authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Use XAttr functions provided by syscall package.

parent e41b8b68
......@@ -26,13 +26,14 @@ func (fs *loopbackFileSystem) StatFs(name string) *fuse.StatfsOut {
}
func (fs *loopbackFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) {
data, errNo := ListXAttr(fs.GetPath(name))
data, err := listXAttr(fs.GetPath(name))
return data, fuse.Status(errNo)
return data, fuse.ToStatus(err)
}
func (fs *loopbackFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
return fuse.Status(Removexattr(fs.GetPath(name), attr))
err := syscall.Removexattr(fs.GetPath(name), attr)
return fuse.ToStatus(err)
}
func (fs *loopbackFileSystem) String() string {
......@@ -41,7 +42,7 @@ func (fs *loopbackFileSystem) String() string {
func (fs *loopbackFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
data := make([]byte, 1024)
data, errNo := GetXAttr(fs.GetPath(name), attr, data)
data, err := getXAttr(fs.GetPath(name), attr, data)
return data, fuse.Status(errNo)
return data, fuse.ToStatus(err)
}
......@@ -3,62 +3,32 @@ package pathfs
import (
"bytes"
"syscall"
"unsafe"
)
func getxattr(path string, attr string, dest []byte) (sz int, errno int) {
pathBs := syscall.StringBytePtr(path)
attrBs := syscall.StringBytePtr(attr)
size, _, errNo := syscall.Syscall6(
syscall.SYS_GETXATTR,
uintptr(unsafe.Pointer(pathBs)),
uintptr(unsafe.Pointer(attrBs)),
uintptr(unsafe.Pointer(&dest[0])),
uintptr(len(dest)),
0, 0)
return int(size), int(errNo)
}
func GetXAttr(path string, attr string, dest []byte) (value []byte, errno int) {
sz, errno := getxattr(path, attr, dest)
for sz > cap(dest) && errno == 0 {
func getXAttr(path string, attr string, dest []byte) (value []byte, err error) {
sz, err := syscall.Getxattr(path, attr, dest)
for sz > cap(dest) && err == nil {
dest = make([]byte, sz)
sz, errno = getxattr(path, attr, dest)
sz, err = syscall.Getxattr(path, attr, dest)
}
if errno != 0 {
return nil, errno
if err != nil {
return nil, err
}
return dest[:sz], errno
return dest[:sz], err
}
func listxattr(path string, dest []byte) (sz int, errno int) {
pathbs := syscall.StringBytePtr(path)
var destPointer unsafe.Pointer
if len(dest) > 0 {
destPointer = unsafe.Pointer(&dest[0])
}
size, _, errNo := syscall.Syscall(
syscall.SYS_LISTXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(destPointer),
uintptr(len(dest)))
return int(size), int(errNo)
}
func ListXAttr(path string) (attributes []string, errno int) {
func listXAttr(path string) (attributes []string, err error) {
dest := make([]byte, 0)
sz, errno := listxattr(path, dest)
if errno != 0 {
return nil, errno
sz, err := syscall.Listxattr(path, dest)
if err != nil {
return nil, err
}
for sz > cap(dest) && errno == 0 {
for sz > cap(dest) && err == nil {
dest = make([]byte, sz)
sz, errno = listxattr(path, dest)
sz, err = syscall.Listxattr(path, dest)
}
// -1 to drop the final empty slice.
......@@ -68,29 +38,6 @@ func ListXAttr(path string) (attributes []string, errno int) {
for i, v := range attributesBytes {
attributes[i] = string(v)
}
return attributes, errno
return attributes, err
}
func Setxattr(path string, attr string, data []byte, flags int) (errno int) {
pathbs := syscall.StringBytePtr(path)
attrbs := syscall.StringBytePtr(attr)
_, _, errNo := syscall.Syscall6(
syscall.SYS_SETXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(unsafe.Pointer(attrbs)),
uintptr(unsafe.Pointer(&data[0])),
uintptr(len(data)),
uintptr(flags), 0)
return int(errNo)
}
func Removexattr(path string, attr string) (errno int) {
pathbs := syscall.StringBytePtr(path)
attrbs := syscall.StringBytePtr(attr)
_, _, errNo := syscall.Syscall(
syscall.SYS_REMOVEXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(unsafe.Pointer(attrbs)), 0)
return int(errNo)
}
......@@ -100,9 +100,9 @@ func (fs *XAttrTestFs) RemoveXAttr(name string, attr string, context *fuse.Conte
return fuse.OK
}
func readXAttr(p, a string) (val []byte, errno int) {
func readXAttr(p, a string) (val []byte, err error) {
val = make([]byte, 1024)
return GetXAttr(p, a, val)
return getXAttr(p, a, val)
}
func xattrTestCase(t *testing.T, nm string) (mountPoint string, cleanup func()) {
......@@ -138,8 +138,8 @@ func TestXAttrNoExist(t *testing.T) {
t.Error("Unexpected stat error", err)
}
val, errno := readXAttr(mounted, "noexist")
if errno == 0 {
val, err := readXAttr(mounted, "noexist")
if err == nil {
t.Error("Expected GetXAttr error", val)
}
}
......@@ -150,15 +150,15 @@ func TestXAttrRead(t *testing.T) {
defer clean()
mounted := filepath.Join(mountPoint, nm)
attrs, errno := ListXAttr(mounted)
attrs, err := listXAttr(mounted)
readback := make(map[string][]byte)
if errno != 0 {
t.Error("Unexpected ListXAttr error", errno)
if err != nil {
t.Error("Unexpected ListXAttr error", err)
} else {
for _, a := range attrs {
val, errno := readXAttr(mounted, a)
if errno != 0 {
t.Errorf("GetXAttr(%q) failed: %v", a, syscall.Errno(errno))
val, err := readXAttr(mounted, a)
if err != nil {
t.Errorf("GetXAttr(%q) failed: %v", a, err)
}
readback[a] = val
}
......@@ -174,18 +174,18 @@ func TestXAttrRead(t *testing.T) {
}
}
errno = Setxattr(mounted, "third", []byte("value"), 0)
if errno != 0 {
t.Error("Setxattr error", errno)
err = syscall.Setxattr(mounted, "third", []byte("value"), 0)
if err != nil {
t.Error("Setxattr error", err)
}
val, errno := readXAttr(mounted, "third")
if errno != 0 || string(val) != "value" {
t.Error("Read back set xattr:", errno, string(val))
val, err := readXAttr(mounted, "third")
if err != nil || string(val) != "value" {
t.Error("Read back set xattr:", err, string(val))
}
Removexattr(mounted, "third")
val, errno = readXAttr(mounted, "third")
if errno != int(fuse.ENODATA) {
t.Error("Data not removed?", errno, val)
syscall.Removexattr(mounted, "third")
val, err = readXAttr(mounted, "third")
if err != syscall.ENODATA {
t.Error("Data not removed?", err, val)
}
}
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