mirror of https://github.com/ceph/go-ceph
cephfs: add file method ListXattr implementing ceph_flistxattr
Add ListXattr implementing ceph_flistxattr. Add a test for the function. Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
parent
a9738e7d45
commit
04bf7a4d0e
|
@ -12,6 +12,7 @@ package cephfs
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ceph/go-ceph/internal/retry"
|
||||
|
@ -97,3 +98,43 @@ func (f *File) GetXattr(name string) ([]byte, error) {
|
|||
}
|
||||
return buf[:ret], nil
|
||||
}
|
||||
|
||||
// ListXattr returns a slice containing strings for the name of each xattr set
|
||||
// on the fie.
|
||||
//
|
||||
// Implements:
|
||||
// int ceph_flistxattr(struct ceph_mount_info *cmount, int fd, char *list, size_t size);
|
||||
func (f *File) ListXattr() ([]string, error) {
|
||||
if err := f.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
ret C.int
|
||||
err error
|
||||
buf []byte
|
||||
)
|
||||
// range from 1k to 64KiB
|
||||
retry.WithSizes(1024, 1<<16, func(size int) retry.Hint {
|
||||
buf = make([]byte, size)
|
||||
ret = C.ceph_flistxattr(
|
||||
f.mount.mount,
|
||||
f.fd,
|
||||
(*C.char)(unsafe.Pointer(&buf[0])),
|
||||
C.size_t(size))
|
||||
err = getErrorIfNegative(ret)
|
||||
return retry.DoubleSize.If(err == errRange)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
names := make([]string, 0)
|
||||
for _, s := range bytes.Split(buf[:ret], []byte{0}) {
|
||||
if len(s) > 0 {
|
||||
name := C.GoString((*C.char)(unsafe.Pointer(&s[0])))
|
||||
names = append(names, name)
|
||||
}
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
|
|
@ -74,5 +74,47 @@ func TestGetSetXattr(t *testing.T) {
|
|||
_, err = f1.GetXattr(samples[0].name)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestListXattr(t *testing.T) {
|
||||
mount := fsConnect(t)
|
||||
defer fsDisconnect(t, mount)
|
||||
fname := "TestListXattr.txt"
|
||||
|
||||
f, err := mount.Open(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
assert.NoError(t, f.Close())
|
||||
assert.NoError(t, mount.Unlink(fname))
|
||||
}()
|
||||
|
||||
t.Run("listXattrs1", func(t *testing.T) {
|
||||
for _, s := range samples[:1] {
|
||||
err := f.SetXattr(s.name, s.value, XattrDefault)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
xl, err := f.ListXattr()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, xl, 1)
|
||||
assert.Contains(t, xl, samples[0].name)
|
||||
})
|
||||
|
||||
t.Run("listXattrs2", func(t *testing.T) {
|
||||
for _, s := range samples[:3] {
|
||||
err := f.SetXattr(s.name, s.value, XattrDefault)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
xl, err := f.ListXattr()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, xl, 3)
|
||||
assert.Contains(t, xl, samples[0].name)
|
||||
assert.Contains(t, xl, samples[1].name)
|
||||
assert.Contains(t, xl, samples[2].name)
|
||||
})
|
||||
|
||||
t.Run("invalidFile", func(t *testing.T) {
|
||||
f1 := &File{}
|
||||
_, err := f1.ListXattr()
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue