Fix sized filesystem

If purging is enabled, overwriting a file with a file of the same
or smaller size will not result in an error.

It is now possible to change the purging mode on an existing sized
filesystem.
This commit is contained in:
Ingo Oppermann
2023-09-22 14:16:46 +02:00
parent 0f4c88be39
commit c3b63c4480
5 changed files with 68 additions and 9 deletions

View File

@@ -426,7 +426,7 @@ func (a *api) start() error {
} else {
a.memfs.SetMetadata("base", baseMemFS.String())
if sizedfs, ok := a.memfs.(fs.SizedFilesystem); ok {
sizedfs.Resize(cfg.Storage.Memory.Size * 1024 * 1024)
sizedfs.Resize(cfg.Storage.Memory.Size*1024*1024, cfg.Storage.Memory.Purge)
}
}

View File

@@ -49,6 +49,6 @@ func (r *readOnlyFilesystem) Purge(size int64) int64 {
return 0
}
func (r *readOnlyFilesystem) Resize(size int64) error {
func (r *readOnlyFilesystem) Resize(size int64, purge bool) error {
return os.ErrPermission
}

View File

@@ -45,6 +45,6 @@ func TestReadOnly(t *testing.T) {
ros, ok := ro.(SizedFilesystem)
require.True(t, ok, "must implement SizedFilesystem")
err = ros.Resize(100)
err = ros.Resize(100, false)
require.Error(t, err)
}

View File

@@ -10,7 +10,7 @@ type SizedFilesystem interface {
Filesystem
// Resize resizes the filesystem to the new size. Files may need to be deleted.
Resize(size int64) error
Resize(size int64, purge bool) error
}
type PurgeFilesystem interface {
@@ -48,7 +48,9 @@ func (r *sizedFilesystem) Size() (int64, int64) {
return currentSize, r.maxSize
}
func (r *sizedFilesystem) Resize(size int64) error {
func (r *sizedFilesystem) Resize(size int64, purge bool) error {
r.purge = purge
currentSize, _ := r.Size()
if size >= currentSize {
// If the new size is the same or larger than the current size,
@@ -82,9 +84,15 @@ func (r *sizedFilesystem) WriteFileReader(path string, rd io.Reader) (int64, boo
return -1, false, fmt.Errorf("File is too big")
}
// Calculate the new size of the filesystem
newSize := currentSize + size
// Calculate the new size of the filesystem
finfo, err := r.Filesystem.Stat(path)
if err == nil {
// If the file already exist, take it's size into account
newSize -= finfo.Size()
}
// If the the new size is larger than the allowed size, we have to free
// some space.
if newSize > maxSize {
@@ -117,9 +125,15 @@ func (r *sizedFilesystem) WriteFileSafe(path string, data []byte) (int64, bool,
return -1, false, fmt.Errorf("File is too big")
}
// Calculate the new size of the filesystem
newSize := currentSize + size
// Calculate the new size of the filesystem
finfo, err := r.Filesystem.Stat(path)
if err == nil {
// If the file already exist, take it's size into account
newSize -= finfo.Size()
}
// If the the new size is larger than the allowed size, we have to free
// some space.
if newSize > maxSize {

View File

@@ -35,7 +35,7 @@ func TestSizedResize(t *testing.T) {
require.Equal(t, int64(0), cur)
require.Equal(t, int64(10), max)
err := fs.Resize(20)
err := fs.Resize(20, false)
require.NoError(t, err)
cur, max = fs.Size()
@@ -44,6 +44,26 @@ func TestSizedResize(t *testing.T) {
require.Equal(t, int64(20), max)
}
func TestSizedResizeSetPurge(t *testing.T) {
fs, _ := NewSizedFilesystem(newMemFS(), 10, false)
_, _, err := fs.WriteFileReader("/foobar1", strings.NewReader("xxxxx"))
require.NoError(t, err)
_, _, err = fs.WriteFileReader("/foobar2", strings.NewReader("xxxxx"))
require.NoError(t, err)
_, _, err = fs.WriteFileReader("/foobar3", strings.NewReader("xxxxx"))
require.Error(t, err)
fs.Resize(10, true)
_, _, err = fs.WriteFileReader("/foobar3", strings.NewReader("xxxxx"))
require.NoError(t, err)
require.Equal(t, int64(2), fs.Files())
}
func TestSizedResizePurge(t *testing.T) {
fs, _ := NewSizedFilesystem(newMemFS(), 10, false)
@@ -59,7 +79,7 @@ func TestSizedResizePurge(t *testing.T) {
require.Equal(t, int64(10), cur)
require.Equal(t, int64(10), max)
err := fs.Resize(5)
err := fs.Resize(5, false)
require.NoError(t, err)
cur, max = fs.Size()
@@ -132,6 +152,31 @@ func TestSizedReplaceNoPurge(t *testing.T) {
cur = fs.Files()
require.Equal(t, int64(1), cur)
data = strings.NewReader("zzzzzzz")
size, created, err = fs.WriteFileReader("/foobar", data)
require.Nil(t, err)
require.Equal(t, int64(7), size)
require.Equal(t, false, created)
cur, max = fs.Size()
require.Equal(t, int64(7), cur)
require.Equal(t, int64(10), max)
cur = fs.Files()
require.Equal(t, int64(1), cur)
data = strings.NewReader("zzzzzzzz")
size, created, err = fs.WriteFileReader("/foobar", data)
require.Nil(t, err)
require.Equal(t, int64(8), size)
require.Equal(t, false, created)
}
func TestSizedReplacePurge(t *testing.T) {