Skip to content

Commit

Permalink
drivers/quota.Control: lock a mutex when called
Browse files Browse the repository at this point in the history
The "quotas" map and "next project ID" field don't take well to being
created and updated concurrently in multiple threads.  Throw a lock
around the whole object when any of its exported methods are called.

Signed-off-by: Nalin Dahyabhai <[email protected]>
  • Loading branch information
nalind committed May 18, 2023
1 parent 561b148 commit edb07d4
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion drivers/quota/projectquota.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import (
"os"
"path"
"path/filepath"
"sync"
"syscall"
"unsafe"

Expand All @@ -80,6 +81,7 @@ type Quota struct {
// Control - Context to be used by storage driver (e.g. overlay)
// who wants to apply project quotas to container dirs
type Control struct {
sync.Mutex // Lock()ed during every call to an exported method
backingFsBlockDev string
nextProjectID uint32
quotas map[string]uint32
Expand Down Expand Up @@ -191,7 +193,8 @@ func NewControl(basePath string) (*Control, error) {
// SetQuota - assign a unique project id to directory and set the quota limits
// for that project id
func (q *Control) SetQuota(targetPath string, quota Quota) error {

q.Lock()
defer q.Unlock()
projectID, ok := q.quotas[targetPath]
if !ok {
projectID = q.nextProjectID
Expand All @@ -218,6 +221,8 @@ func (q *Control) SetQuota(targetPath string, quota Quota) error {
// ClearQuota removes the map entry in the quotas map for targetPath.
// It does so to prevent the map leaking entries as directories are deleted.
func (q *Control) ClearQuota(targetPath string) {
q.Lock()
defer q.Unlock()
delete(q.quotas, targetPath)
}

Expand Down Expand Up @@ -275,6 +280,8 @@ func (q *Control) setProjectQuota(projectID uint32, quota Quota) error {

// GetQuota - get the quota limits of a directory that was configured with SetQuota
func (q *Control) GetQuota(targetPath string, quota *Quota) error {
q.Lock()
defer q.Unlock()
d, err := q.fsDiskQuotaFromPath(targetPath)
if err != nil {
return err
Expand All @@ -286,6 +293,8 @@ func (q *Control) GetQuota(targetPath string, quota *Quota) error {

// GetDiskUsage - get the current disk usage of a directory that was configured with SetQuota
func (q *Control) GetDiskUsage(targetPath string, usage *directory.DiskUsage) error {
q.Lock()
defer q.Unlock()
d, err := q.fsDiskQuotaFromPath(targetPath)
if err != nil {
return err
Expand Down

0 comments on commit edb07d4

Please sign in to comment.