Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

decomposedfs: add locking support #2460

Merged
merged 59 commits into from
Feb 9, 2022
Merged
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
6947e24
decomposedfs: add locking support
butonic Jan 20, 2022
4649185
add lock implementation, refactor error handling
butonic Jan 21, 2022
2c7f7d3
introduce lock ctx
butonic Jan 28, 2022
d0d0725
add locked error and status code mapping
butonic Jan 28, 2022
8e753e9
read lockid from opaque into ctx for delete
butonic Jan 28, 2022
a5bfd6a
decomposedfs: make delete respect lock
butonic Jan 28, 2022
d45b84c
ocdav: simplify error code mapping
butonic Jan 28, 2022
9d5fe9d
adjust to cs3 lock api update
butonic Jan 28, 2022
b9ac3f5
utils: add and read plain opaque entries
butonic Jan 28, 2022
3630238
fix delete lock
butonic Jan 28, 2022
0def9fd
invalidate stat cache when setting lock
butonic Jan 28, 2022
59e7bf1
fix a few linter items
butonic Jan 28, 2022
a07f4bf
linter happyness
butonic Jan 28, 2022
65376ae
ocdav: implment unlock
butonic Jan 28, 2022
96e4e09
lock caching and unlocking
butonic Jan 28, 2022
35e0eab
read locks on folders
butonic Jan 28, 2022
942f8ea
check lock on writes
butonic Jan 28, 2022
e5ea694
always assume locktype write
butonic Jan 31, 2022
d052abf
ocis only supports exclusive locks
butonic Jan 31, 2022
c6e394d
add precodition failed errtype
butonic Jan 31, 2022
e425727
handle preconditionfailed in status conversion
butonic Jan 31, 2022
f427862
omit empty xml tags in lockdiscovery
butonic Jan 31, 2022
4c95a65
handle locked status on LOCK
butonic Jan 31, 2022
78880f9
document oc10 lock behaviour as comment
butonic Jan 31, 2022
91f255a
ocdav: handle errors for LOCK and UNLOCK
butonic Jan 31, 2022
826dcf9
storage: change fs.Unlock signature
butonic Jan 31, 2022
9024756
decomposedfs: refactor checkLock
butonic Jan 31, 2022
5c07bed
add LookupReferenceForPath comment
butonic Feb 1, 2022
56b9f34
gateway: ignore unimplemented add/denyGrant response
butonic Feb 1, 2022
bcd2bca
use http.StatusMethodNotAllowed for mkcol error case
butonic Feb 1, 2022
a1a3e1e
make hound happy
butonic Feb 1, 2022
c36b3bd
ocdav: be more tolerant with the Lock-Token header
butonic Feb 1, 2022
025ea39
ocdav: allow setting infinity timeout
butonic Feb 1, 2022
10b97f9
ocdav: use custem owner innerxml without href
butonic Feb 1, 2022
52f1bdd
update expected failures
butonic Feb 1, 2022
9fa4418
ocdav: return conflict on missing intermediate target dir
butonic Feb 1, 2022
87f8fb6
decomposedfs: use checkLock() in the rest of cases
butonic Feb 1, 2022
02631d2
Do not choke when checking the lock of non-existent nodes
aduffeck Feb 3, 2022
c413855
Linter fixes
aduffeck Feb 3, 2022
e26a5a6
Refactor: Move lock handling into the node domain
aduffeck Feb 3, 2022
870033a
Also delete the lock file when deleting a node
aduffeck Feb 3, 2022
22e6d1e
Extract node lock-handling code into separate file, start writing tests
aduffeck Feb 3, 2022
a8efa41
Add missing license header
aduffeck Feb 3, 2022
8dfc038
Fix relocking already-locked nodes. Increase test coverage
aduffeck Feb 3, 2022
71315ad
Hounds be happy
aduffeck Feb 3, 2022
94dec27
Add unit tests for ReadLock and RefreshLock
aduffeck Feb 4, 2022
507f3c7
Also cover readLocksIntoOpaque in the tests
aduffeck Feb 4, 2022
24fc295
Fix linter issue
aduffeck Feb 4, 2022
2e9a353
Do not log full nodes, it's very expensive and not very helpful
aduffeck Feb 4, 2022
5e24a0c
Start adding grpc integration tests for locking
aduffeck Feb 4, 2022
40346bb
Fix setting the lock for file uploads
aduffeck Feb 4, 2022
c6ec33e
Allow for locking space-based resources
aduffeck Feb 7, 2022
c6565bc
Make sure to log the error before it's getting overwritten
aduffeck Feb 7, 2022
8a16f01
reuse xml.EscapeText directly
butonic Feb 8, 2022
00be883
decomposedfs: use defer to close file when unlocking resource
butonic Feb 8, 2022
4f67281
ocdav: explain why some http states are commented
butonic Feb 8, 2022
59c90bc
ocdav: use http header status constants
butonic Feb 8, 2022
047d843
clarify add/deny grant log
butonic Feb 8, 2022
d742652
update expected failures
butonic Feb 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog/unreleased/decomposedfs-locking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: add locking support to decomposedfs

The decomposedfs now implements application level locking

https://github.com/cs3org/reva/pull/2460
3 changes: 3 additions & 0 deletions internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
@@ -743,6 +743,7 @@ func (s *svc) SetLock(ctx context.Context, req *provider.SetLockRequest) (*provi
return nil, errors.Wrap(err, "gateway: error calling SetLock")
}

s.cache.RemoveStat(ctxpkg.ContextMustGetUser(ctx), req.Ref.ResourceId)
return res, nil
}

@@ -783,6 +784,7 @@ func (s *svc) RefreshLock(ctx context.Context, req *provider.RefreshLockRequest)
return nil, errors.Wrap(err, "gateway: error calling RefreshLock")
}

s.cache.RemoveStat(ctxpkg.ContextMustGetUser(ctx), req.Ref.ResourceId)
return res, nil
}

@@ -803,6 +805,7 @@ func (s *svc) Unlock(ctx context.Context, req *provider.UnlockRequest) (*provide
return nil, errors.Wrap(err, "gateway: error calling Unlock")
}

s.cache.RemoveStat(ctxpkg.ContextMustGetUser(ctx), req.Ref.ResourceId)
return res, nil
}

39 changes: 15 additions & 24 deletions internal/grpc/services/gateway/usershareprovider.go
Original file line number Diff line number Diff line change
@@ -66,26 +66,27 @@ func (s *svc) CreateShare(ctx context.Context, req *collaboration.CreateShareReq
// TODO(labkode): if both commits are enabled they could be done concurrently.
if s.c.CommitShareToStorageGrant {
// If the share is a denial we call denyGrant instead.
var status *rpc.Status
if grants.PermissionsEqual(req.Grant.Permissions.Permissions, &provider.ResourcePermissions{}) {
denyGrantStatus, err := s.denyGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee)
status, err = s.denyGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee)
if err != nil {
return nil, errors.Wrap(err, "gateway: error denying grant in storage")
}
if denyGrantStatus.Code != rpc.Code_CODE_OK {
return &collaboration.CreateShareResponse{
Status: denyGrantStatus,
}, err
} else {
status, err = s.addGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, req.Grant.Permissions.Permissions)
if err != nil {
return nil, errors.Wrap(err, "gateway: error adding grant to storage")
}
return res, nil
}

addGrantStatus, err := s.addGrant(ctx, req.ResourceInfo.Id, req.Grant.Grantee, req.Grant.Permissions.Permissions)
if err != nil {
return nil, errors.Wrap(err, "gateway: error adding grant to storage")
}
if addGrantStatus.Code != rpc.Code_CODE_OK {
switch status.Code {
case rpc.Code_CODE_OK:
// ok
case rpc.Code_CODE_UNIMPLEMENTED:
appctx.GetLogger(ctx).Debug().Interface("status", status).Interface("req", req).Msg("storing grants not supported, ignoring")
default:
return &collaboration.CreateShareResponse{
Status: addGrantStatus,
Status: status,
}, err
}
}
@@ -493,12 +494,7 @@ func (s *svc) denyGrant(ctx context.Context, id *provider.ResourceId, g *provide
if err != nil {
return nil, errors.Wrap(err, "gateway: error calling DenyGrant")
}
if grantRes.Status.Code != rpc.Code_CODE_OK {
return status.NewInternal(ctx,
"error committing share to storage grant"), nil
}

return status.NewOK(ctx), nil
return grantRes.Status, nil
}

func (s *svc) addGrant(ctx context.Context, id *provider.ResourceId, g *provider.Grantee, p *provider.ResourcePermissions) (*rpc.Status, error) {
@@ -530,12 +526,7 @@ func (s *svc) addGrant(ctx context.Context, id *provider.ResourceId, g *provider
if err != nil {
return nil, errors.Wrap(err, "gateway: error calling AddGrant")
}
if grantRes.Status.Code != rpc.Code_CODE_OK {
return status.NewInternal(ctx,
"error committing share to storage grant"), nil
}

return status.NewOK(ctx), nil
return grantRes.Status, nil
}

func (s *svc) updateGrant(ctx context.Context, id *provider.ResourceId, g *provider.Grantee, p *provider.ResourcePermissions) (*rpc.Status, error) {
Loading