mirror of https://github.com/ceph/go-ceph
cephfs: add File method Truncate implementing ceph_ftruncate
Add a Truncate method to File type. Note the doc comment as I hit a bug in ceph when writing the first test cases. Go-ceph will behave as ceph here - so using go-ceph with an unfixed version of the ceph libs will also exhibit the bug. Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
parent
0afcf98b34
commit
e2de2b6e58
|
@ -391,3 +391,25 @@ func (f *File) Fsync(sync SyncChoice) error {
|
|||
func (f *File) Sync() error {
|
||||
return f.Fsync(SyncAll)
|
||||
}
|
||||
|
||||
// Truncate sets the size of the open file.
|
||||
// NOTE: In some versions of ceph a bug exists where calling ftruncate on a
|
||||
// file open for read-only is permitted. The go-ceph wrapper does no additional
|
||||
// checking and will inherit the issue on affected versions of ceph. Please
|
||||
// refer to the following issue for details:
|
||||
// https://tracker.ceph.com/issues/48202
|
||||
//
|
||||
// Implements:
|
||||
// int ceph_ftruncate(struct ceph_mount_info *cmount, int fd, int64_t size);
|
||||
func (f *File) Truncate(size int64) error {
|
||||
if err := f.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ret := C.ceph_ftruncate(
|
||||
f.mount.mount,
|
||||
f.fd,
|
||||
C.int64_t(size),
|
||||
)
|
||||
return getError(ret)
|
||||
}
|
||||
|
|
|
@ -918,3 +918,54 @@ func TestFilePreadvPwritev(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestFileTruncate(t *testing.T) {
|
||||
mount := fsConnect(t)
|
||||
defer fsDisconnect(t, mount)
|
||||
|
||||
fname := "TestFileTruncate.txt"
|
||||
defer mount.Unlink(fname)
|
||||
|
||||
t.Run("invalidSize", func(t *testing.T) {
|
||||
// "touch" the file
|
||||
f1, err := mount.Open(fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
assert.NoError(t, f1.Close())
|
||||
}()
|
||||
|
||||
err = f1.Truncate(-1)
|
||||
assert.Error(t, err)
|
||||
|
||||
st, err := f1.Fstatx(StatxBasicStats, 0)
|
||||
if assert.NoError(t, err) {
|
||||
assert.EqualValues(t, 0, st.Size)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("closedFile", func(t *testing.T) {
|
||||
t.Skip("test fails because of a bug(?) in ceph")
|
||||
// "touch" the file
|
||||
f1, err := mount.Open(fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, f1.Close())
|
||||
|
||||
f2, err := mount.Open(fname, os.O_RDONLY, 0644)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, f2.Close())
|
||||
|
||||
err = f2.Truncate(1024)
|
||||
assert.Error(t, err)
|
||||
|
||||
// I wanted to do the stat check here too but it is a pain to implement
|
||||
// because we close the file.
|
||||
// The original version of this test, using a read-only file, failed
|
||||
// due to a bug in libcephfs (see Truncate doc comment).
|
||||
})
|
||||
|
||||
t.Run("invalidFile", func(t *testing.T) {
|
||||
f := &File{}
|
||||
err := f.Truncate(0)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue