From 6a0a5164f9d70af05059867d07c19c31eb132a70 Mon Sep 17 00:00:00 2001 From: David Christofas Date: Fri, 13 May 2022 10:18:25 +0200 Subject: [PATCH] don't include versions in quota check (#2863) --- changelog/unreleased/versions-quota.md | 6 +++++ pkg/storage/utils/decomposedfs/node/node.go | 23 ++++++++++++------- pkg/storage/utils/decomposedfs/upload.go | 10 ++++++-- pkg/storage/utils/decomposedfs/upload_test.go | 2 +- 4 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 changelog/unreleased/versions-quota.md diff --git a/changelog/unreleased/versions-quota.md b/changelog/unreleased/versions-quota.md new file mode 100644 index 0000000000..fdb422a5cd --- /dev/null +++ b/changelog/unreleased/versions-quota.md @@ -0,0 +1,6 @@ +Bugfix: Don't include versions in quota + +Fixed the quota check to not count the quota of previous versions. + +https://github.com/owncloud/ocis/issues/2829 +https://github.com/cs3org/reva/pull/2863 diff --git a/pkg/storage/utils/decomposedfs/node/node.go b/pkg/storage/utils/decomposedfs/node/node.go index 137f029a99..fe5d592401 100644 --- a/pkg/storage/utils/decomposedfs/node/node.go +++ b/pkg/storage/utils/decomposedfs/node/node.go @@ -1108,20 +1108,27 @@ func IsSpaceRoot(r *Node) bool { } // CheckQuota checks if both disk space and available quota are sufficient -var CheckQuota = func(spaceRoot *Node, fileSize uint64) (quotaSufficient bool, err error) { +// Overwrite must be set to true if the new file replaces the old file e.g. +// when creating a new file version. In such a case the function will +// reduce the used bytes by the old file size and then add the new size. +// If overwrite is false oldSize will be ignored. +var CheckQuota = func(spaceRoot *Node, overwrite bool, oldSize, newSize uint64) (quotaSufficient bool, err error) { used, _ := spaceRoot.GetTreeSize() - if !enoughDiskSpace(spaceRoot.InternalPath(), fileSize) { + if !enoughDiskSpace(spaceRoot.InternalPath(), newSize) { return false, errtypes.InsufficientStorage("disk full") } - quotaByte, _ := xattrs.Get(spaceRoot.InternalPath(), xattrs.QuotaAttr) - var total uint64 - if quotaByte == "" { + quotaByteStr, _ := xattrs.Get(spaceRoot.InternalPath(), xattrs.QuotaAttr) + if quotaByteStr == "" { // if quota is not set, it means unlimited return true, nil } - total, _ = strconv.ParseUint(quotaByte, 10, 64) - // if total is smaller than used, total-used could overflow and be bigger than fileSize - if fileSize > total-used || total < used { + quotaByte, _ := strconv.ParseUint(quotaByteStr, 10, 64) + if overwrite { + if quotaByte < used-oldSize+newSize { + return false, errtypes.InsufficientStorage("quota exceeded") + } + // if total is smaller than used, total-used could overflow and be bigger than fileSize + } else if newSize > quotaByte-used || quotaByte < used { return false, errtypes.InsufficientStorage("quota exceeded") } return true, nil diff --git a/pkg/storage/utils/decomposedfs/upload.go b/pkg/storage/utils/decomposedfs/upload.go index 869f41d254..f3bf980178 100644 --- a/pkg/storage/utils/decomposedfs/upload.go +++ b/pkg/storage/utils/decomposedfs/upload.go @@ -154,7 +154,7 @@ func (fs *Decomposedfs) InitiateUpload(ctx context.Context, ref *provider.Refere log.Debug().Interface("info", info).Interface("node", n).Interface("metadata", metadata).Msg("Decomposedfs: resolved filename") - _, err = node.CheckQuota(n.SpaceRoot, uint64(info.Size)) + _, err = node.CheckQuota(n.SpaceRoot, n.Exists, uint64(n.Blobsize), uint64(info.Size)) if err != nil { return nil, err } @@ -481,7 +481,13 @@ func (upload *fileUpload) FinishUpload(ctx context.Context) (err error) { return err } - _, err = node.CheckQuota(n.SpaceRoot, uint64(fi.Size())) + var oldSize uint64 + if n.ID != "" { + old, _ := node.ReadNode(ctx, upload.fs.lu, spaceID, n.ID) + oldSize = uint64(old.Blobsize) + } + _, err = node.CheckQuota(n.SpaceRoot, n.ID != "", oldSize, uint64(fi.Size())) + if err != nil { return err } diff --git a/pkg/storage/utils/decomposedfs/upload_test.go b/pkg/storage/utils/decomposedfs/upload_test.go index f1722f5124..010d83e8c5 100644 --- a/pkg/storage/utils/decomposedfs/upload_test.go +++ b/pkg/storage/utils/decomposedfs/upload_test.go @@ -130,7 +130,7 @@ var _ = Describe("File uploads", func() { When("the user wants to initiate a file upload", func() { It("fails", func() { var originalFunc = node.CheckQuota - node.CheckQuota = func(spaceRoot *node.Node, fileSize uint64) (quotaSufficient bool, err error) { + node.CheckQuota = func(spaceRoot *node.Node, overwrite bool, oldSize, newSize uint64) (quotaSufficient bool, err error) { return false, errtypes.InsufficientStorage("quota exceeded") } _, err := fs.InitiateUpload(ctx, ref, 10, map[string]string{})