Skip to content

Commit

Permalink
check lock on writes
Browse files Browse the repository at this point in the history
Signed-off-by: Jörn Friedrich Dreyer <[email protected]>
  • Loading branch information
butonic committed Jan 28, 2022
1 parent 0af5690 commit f09d0a5
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 33 deletions.
54 changes: 25 additions & 29 deletions pkg/storage/utils/decomposedfs/decomposedfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,14 @@ func (fs *Decomposedfs) CreateDir(ctx context.Context, ref *provider.Reference)
return errtypes.PermissionDenied(filepath.Join(n.ParentID, n.Name))
}

// check lock
if lock := n.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

// verify child does not exist, yet
if n, err = n.Child(ctx, name); err != nil {
return
Expand Down Expand Up @@ -434,7 +442,13 @@ func (fs *Decomposedfs) Move(ctx context.Context, oldRef, newRef *provider.Refer
return
}

// FIXME check is locked
// check lock on target
if lock := newNode.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId) // return we must return the current lockid
}
}

return fs.tp.Move(ctx, oldNode, newNode)
}
Expand Down Expand Up @@ -524,34 +538,11 @@ func (fs *Decomposedfs) Delete(ctx context.Context, ref *provider.Reference) (er
return errtypes.PermissionDenied(filepath.Join(node.ParentID, node.Name))
}

// WebDAV uses the Token
/*
from https://datatracker.ietf.org/doc/html/rfc4918#section-7
Of the methods defined in HTTP and WebDAV, PUT, POST, PROPPATCH,
LOCK, UNLOCK, MOVE, COPY (for the destination resource), DELETE, and
MKCOL are affected by write locks. All other HTTP/WebDAV methods
defined so far -- GET in particular -- function independently of a
write lock.
from https://datatracker.ietf.org/doc/html/rfc4918#section-7.5
In order to prevent these collisions, a lock token MUST be submitted
by an authorized principal for all locked resources that a method may
change or the method MUST fail. A lock token is submitted when it
appears in an If header. For example, if a resource is to be moved
and both the source and destination are locked, then two lock tokens
must be submitted in the If header, one for the source and the other
for the destination.
If: <http://www.example.com/users/f/fielding/index.html>
(<urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>)
*/
// check lock
if lock := node.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId) // return we must return the current lockid
return errtypes.Locked(lock.LockId)
}
}

Expand Down Expand Up @@ -649,10 +640,15 @@ func (fs *Decomposedfs) SetLock(ctx context.Context, ref *provider.Reference, lo
return errtypes.PermissionDenied(filepath.Join(node.ParentID, node.Name))
}

lockPath := node.InternalPath() + ".lock"

// FIXME check is locked
// check lock
if lock := node.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

lockPath := node.InternalPath() + ".lock"
// O_EXCL to make open fail when the file already exists
f, err := os.OpenFile(lockPath, os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
Expand Down
17 changes: 15 additions & 2 deletions pkg/storage/utils/decomposedfs/grants.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
ctxpkg "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/storage/utils/ace"
"github.com/cs3org/reva/pkg/storage/utils/decomposedfs/node"
Expand Down Expand Up @@ -62,7 +63,13 @@ func (fs *Decomposedfs) AddGrant(ctx context.Context, ref *provider.Reference, g
return errtypes.PermissionDenied(filepath.Join(node.ParentID, node.Name))
}

// FIXME check is locked
// check lock
if lock := node.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

np := fs.lu.InternalPath(node.ID)
e := ace.FromGrant(g)
Expand Down Expand Up @@ -144,7 +151,13 @@ func (fs *Decomposedfs) RemoveGrant(ctx context.Context, ref *provider.Reference
return errtypes.PermissionDenied(filepath.Join(node.ParentID, node.Name))
}

// FIXME check is locked
// check lock
if lock := node.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

var attr string
if g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP {
Expand Down
16 changes: 16 additions & 0 deletions pkg/storage/utils/decomposedfs/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ func (fs *Decomposedfs) SetArbitraryMetadata(ctx context.Context, ref *provider.
return errtypes.PermissionDenied(filepath.Join(n.ParentID, n.Name))
}

// check lock
if lock := n.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

nodePath := n.InternalPath()

errs := []error{}
Expand Down Expand Up @@ -148,6 +156,14 @@ func (fs *Decomposedfs) UnsetArbitraryMetadata(ctx context.Context, ref *provide
return errtypes.PermissionDenied(filepath.Join(n.ParentID, n.Name))
}

// check lock
if lock := n.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

nodePath := n.InternalPath()
errs := []error{}
for _, k := range keys {
Expand Down
9 changes: 8 additions & 1 deletion pkg/storage/utils/decomposedfs/recycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
ctxpkg "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/storage/utils/decomposedfs/node"
"github.com/cs3org/reva/pkg/storage/utils/decomposedfs/xattrs"
Expand Down Expand Up @@ -279,7 +280,13 @@ func (fs *Decomposedfs) RestoreRecycleItem(ctx context.Context, ref *provider.Re
return errtypes.PermissionDenied(key)
}

// FIXME check is locked
// check lock
if lock := targetNode.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

// Run the restore func
return restoreFunc()
Expand Down
9 changes: 8 additions & 1 deletion pkg/storage/utils/decomposedfs/revisions.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (

provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
ctxpkg "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/storage/utils/decomposedfs/node"
"github.com/pkg/errors"
Expand Down Expand Up @@ -165,7 +166,13 @@ func (fs *Decomposedfs) RestoreRevision(ctx context.Context, ref *provider.Refer
return errtypes.PermissionDenied(filepath.Join(n.ParentID, n.Name))
}

// FIXME check is locked
// check lock
if lock := n.ReadLock(ctx); lock != nil {
lockID, _ := ctxpkg.ContextGetLockID(ctx)
if lock.LockId != lockID {
return errtypes.Locked(lock.LockId)
}
}

// move current version to new revision
nodePath := fs.lu.InternalPath(kp[0])
Expand Down

0 comments on commit f09d0a5

Please sign in to comment.