diff --git a/app/api/api.go b/app/api/api.go index 695b7f40..017c9cef 100644 --- a/app/api/api.go +++ b/app/api/api.go @@ -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) } } diff --git a/io/fs/readonly.go b/io/fs/readonly.go index 889672a4..b7692882 100644 --- a/io/fs/readonly.go +++ b/io/fs/readonly.go @@ -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 } diff --git a/io/fs/readonly_test.go b/io/fs/readonly_test.go index 13360b47..53778296 100644 --- a/io/fs/readonly_test.go +++ b/io/fs/readonly_test.go @@ -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) } diff --git a/io/fs/sized.go b/io/fs/sized.go index 366ef6f5..63e80126 100644 --- a/io/fs/sized.go +++ b/io/fs/sized.go @@ -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 { diff --git a/io/fs/sized_test.go b/io/fs/sized_test.go index e158c422..ff72dd46 100644 --- a/io/fs/sized_test.go +++ b/io/fs/sized_test.go @@ -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) {