rbd: fix problems with Image.Discard()

The return value of rbd_discard() is the number of bytes that have been
discarded, or in case of an error, a negative errno value.

It seems Image.Discard() never can have worked as intended, unless the
error was disregarded. Just like Image.Write(), Image.Discard() should
return a tuple of the number of bytes discarded and an error.

Fixes: ceph/go-ceph#123
Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos 2019-12-10 12:57:29 +01:00 committed by John Mulligan
parent 9381485fac
commit 22c15e5a37
2 changed files with 55 additions and 4 deletions

View File

@ -885,13 +885,17 @@ func (image *Image) Seek(offset int64, whence int) (int64, error) {
}
// int rbd_discard(rbd_image_t image, uint64_t ofs, uint64_t len);
func (image *Image) Discard(ofs uint64, length uint64) error {
func (image *Image) Discard(ofs uint64, length uint64) (int, error) {
if err := image.validate(imageIsOpen); err != nil {
return err
return 0, err
}
return RBDError(C.rbd_discard(image.image, C.uint64_t(ofs),
C.uint64_t(length)))
ret := C.rbd_discard(image.image, C.uint64_t(ofs), C.uint64_t(length))
if ret < 0 {
return 0, RBDError(ret)
}
return int(ret), nil
}
func (image *Image) ReadAt(data []byte, off int64) (n int, err error) {

View File

@ -462,6 +462,53 @@ func TestImageSeek(t *testing.T) {
conn.Shutdown()
}
func TestImageDiscard(t *testing.T) {
conn, _ := rados.NewConn()
conn.ReadDefaultConfigFile()
conn.Connect()
poolname := GetUUID()
err := conn.MakePool(poolname)
assert.NoError(t, err)
ioctx, err := conn.OpenIOContext(poolname)
require.NoError(t, err)
name := GetUUID()
img, err := Create(ioctx, name, 1<<22, 22)
assert.NoError(t, err)
err = img.Open()
assert.NoError(t, err)
n, err := img.Discard(0, 1<<16)
assert.NoError(t, err)
assert.Equal(t, n, 1<<16)
err = img.Close()
assert.NoError(t, err)
err = img.Open(true)
assert.NoError(t, err)
// when read-only, discard should fail
_, err = img.Discard(0, 1<<16)
assert.Error(t, err)
err = img.Close()
assert.NoError(t, err)
_, err = img.Discard(0, 1<<16)
assert.Equal(t, err, ErrImageNotOpen)
err = img.Remove()
assert.NoError(t, err)
ioctx.Destroy()
conn.DeletePool(poolname)
conn.Shutdown()
}
func TestIOReaderWriter(t *testing.T) {
conn, _ := rados.NewConn()
conn.ReadDefaultConfigFile()