Skip to content

Commit

Permalink
refactor checkQuota
Browse files Browse the repository at this point in the history
  • Loading branch information
micbar committed Oct 18, 2021
1 parent d0d8b9b commit b10384e
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 42 deletions.
2 changes: 1 addition & 1 deletion pkg/storage/utils/decomposedfs/decomposedfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func (fs *Decomposedfs) GetQuota(ctx context.Context, ref *provider.Reference) (
quotaStr = string(ri.Opaque.Map["quota"].Value)
}

avail, err := fs.getAvailableSize(n.InternalPath())
avail, err := node.GetAvailableSize(n.InternalPath())
if err != nil {
return 0, 0, err
}
Expand Down
28 changes: 28 additions & 0 deletions pkg/storage/utils/decomposedfs/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,3 +938,31 @@ func parseMTime(v string) (t time.Time, err error) {
}
return time.Unix(sec, nsec), err
}

// CheckQuota checks if both disk space and available quota are sufficient
var CheckQuota = func(spaceRoot *Node, fileSize uint64) (quotaSufficient bool, err error) {
used, _ := spaceRoot.GetTreeSize()
if !enoughDiskSpace(spaceRoot.InternalPath(), fileSize) {
return false, errtypes.InsufficientStorage("disk full")
}
quotaByte, _ := xattr.Get(spaceRoot.InternalPath(), xattrs.QuotaAttr)
var total uint64
if quotaByte == nil {
// if quota is not set, it means unlimited
return true, nil
}
total, _ = strconv.ParseUint(string(quotaByte), 10, 64)
// if total is smaller that used, total-used could overflow and be bigger than fileSize
if fileSize > total-used || total < used {
return false, errtypes.InsufficientStorage("quota exceeded")
}
return true, nil
}

func enoughDiskSpace(path string, fileSize uint64) bool {
avalB, err := GetAvailableSize(path)
if err != nil {
return false
}
return avalB > fileSize
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
//go:build !windows
// +build !windows

package decomposedfs
package node

import "syscall"

func (fs *Decomposedfs) getAvailableSize(path string) (uint64, error) {
// GetAvailableSize stats the filesystem and return the available bytes
func GetAvailableSize(path string) (uint64, error) {
stat := syscall.Statfs_t{}
err := syscall.Statfs(path, &stat)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
//go:build windows
// +build windows

package decomposedfs
package node

import "golang.org/x/sys/windows"

func (fs *Decomposedfs) getAvailableSize(path string) (uint64, error) {
// GetAvailableSize stats the filesystem and return the available bytes
func GetAvailableSize(path string) (uint64, error) {
var free, total, avail uint64
pathPtr, err := windows.UTF16PtrFromString(path)
if err != nil {
Expand Down
36 changes: 2 additions & 34 deletions pkg/storage/utils/decomposedfs/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"time"

Expand All @@ -43,11 +42,9 @@ import (
"github.com/cs3org/reva/pkg/logger"
"github.com/cs3org/reva/pkg/storage/utils/chunking"
"github.com/cs3org/reva/pkg/storage/utils/decomposedfs/node"
"github.com/cs3org/reva/pkg/storage/utils/decomposedfs/xattrs"
"github.com/cs3org/reva/pkg/utils"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/pkg/xattr"
"github.com/rs/zerolog"
tusd "github.com/tus/tusd/pkg/handler"
)
Expand Down Expand Up @@ -110,35 +107,6 @@ func (fs *Decomposedfs) Upload(ctx context.Context, ref *provider.Reference, r i
return uploadInfo.FinishUpload(ctx)
}

// CheckQuota checks if both disk space and available quota are sufficient
var CheckQuota = func(ctx context.Context, fs *Decomposedfs, spaceRoot *node.Node, fileSize uint64) (quotaSufficient bool, err error) {
used, _ := spaceRoot.GetTreeSize()
if !enoughDiskSpace(fs, spaceRoot.InternalPath(), fileSize) {
return false, errtypes.InsufficientStorage("disk full")
}
quotaByte, _ := xattr.Get(spaceRoot.InternalPath(), xattrs.QuotaAttr)
var total uint64
if quotaByte == nil {
// if quota is not set, it means unlimited
return true, nil
}
total, _ = strconv.ParseUint(string(quotaByte), 10, 64)
// if total is smaller that used, total-used could overflow and be bigger than fileSize
if fileSize > total-used || total < used {
return false, errtypes.InsufficientStorage("quota exceeded")
}
return true, nil
}

func enoughDiskSpace(fs *Decomposedfs, path string, fileSize uint64) bool {
avalB, err := fs.getAvailableSize(path)
if err != nil {
return false
}

return avalB > fileSize
}

// InitiateUpload returns upload ids corresponding to different protocols it supports
// TODO read optional content for small files in this request
// TODO InitiateUpload (and Upload) needs a way to receive the expected checksum. Maybe in metadata as 'checksum' => 'sha1 aeosvp45w5xaeoe' = lowercase, space separated?
Expand Down Expand Up @@ -192,7 +160,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 = CheckQuota(ctx, fs, n.SpaceRoot, uint64(info.Size))
_, err = node.CheckQuota(n.SpaceRoot, uint64(info.Size))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -515,7 +483,7 @@ func (upload *fileUpload) FinishUpload(ctx context.Context) (err error) {
)
n.SpaceRoot = node.New(upload.info.Storage["SpaceRoot"], "", "", 0, "", nil, upload.fs.lu)

_, err = CheckQuota(upload.ctx, upload.fs, n.SpaceRoot, uint64(fi.Size()))
_, err = node.CheckQuota(n.SpaceRoot, uint64(fi.Size()))
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/storage/utils/decomposedfs/upload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ var _ = Describe("File uploads", func() {
Context("quota exceeded", func() {
Describe("InitiateUpload", func() {
It("fails", func() {
var originalFunc = decomposedfs.CheckQuota
decomposedfs.CheckQuota = func(ctx context.Context, fs *decomposedfs.Decomposedfs, spaceRoot *node.Node, fileSize uint64) (quotaSufficient bool, err error) {
var originalFunc = node.CheckQuota
node.CheckQuota = func(spaceRoot *node.Node, fileSize uint64) (quotaSufficient bool, err error) {
return false, errtypes.InsufficientStorage("quota exceeded")
}
_, err := fs.InitiateUpload(ctx, ref, 10, map[string]string{})
Expect(err).To(MatchError(errtypes.InsufficientStorage("quota exceeded")))
decomposedfs.CheckQuota = originalFunc
node.CheckQuota = originalFunc
})
})
})
Expand Down

0 comments on commit b10384e

Please sign in to comment.