Skip to content

Commit c2c5a45

Browse files
dragotinDavid Christofasbutonic
committed
Some error cleanup steps in the decomposed FS (#2511)
* Some error cleanup steps in the decomposed FS * Hound and changelog added. * Remove punctuation * Make CI happy * Improved error logging. Co-authored-by: David Christofas <[email protected]> * Update pkg/storage/utils/decomposedfs/decomposedfs.go Co-authored-by: David Christofas <[email protected]> Co-authored-by: David Christofas <[email protected]> Co-authored-by: Jörn Friedrich Dreyer <[email protected]>
1 parent b522aab commit c2c5a45

File tree

3 files changed

+59
-14
lines changed

3 files changed

+59
-14
lines changed

changelog/unreleased/clean-dfs1.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Enhancement: Error handling cleanup in decomposed FS
2+
3+
- Avoid inconsensitencies by cleaning up actions in case of err
4+
5+
https://github.com/cs3org/reva/pull/2511

pkg/storage/utils/decomposedfs/decomposedfs.go

+51-13
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,17 @@ func (fs *Decomposedfs) CreateHome(ctx context.Context) (err error) {
217217
}
218218
return nil
219219
})
220+
221+
// make sure to delete the created directory if things go wrong
222+
defer func() {
223+
if err != nil {
224+
// do not catch the error to not shadow the original error
225+
if tmpErr := fs.tp.Delete(ctx, n); tmpErr != nil {
226+
appctx.GetLogger(ctx).Error().Err(tmpErr).Msg("Can not revert file system change after error")
227+
}
228+
}
229+
}()
230+
220231
if err != nil {
221232
return
222233
}
@@ -333,6 +344,9 @@ func (fs *Decomposedfs) CreateDir(ctx context.Context, ref *provider.Reference)
333344
// mark the home node as the end of propagation
334345
if err = xattr.Set(nodePath, xattrs.PropagationAttr, []byte("1")); err != nil {
335346
appctx.GetLogger(ctx).Error().Err(err).Interface("node", n).Msg("could not mark node to propagate")
347+
348+
// FIXME: This does not return an error at all, but results in a severe situation that the
349+
// part tree is not marked for propagation
336350
return
337351
}
338352
}
@@ -345,9 +359,10 @@ func (fs *Decomposedfs) TouchFile(ctx context.Context, ref *provider.Reference)
345359
}
346360

347361
// CreateReference creates a reference as a node folder with the target stored in extended attributes
348-
// There is no difference between the /Shares folder and normal nodes because the storage is not supposed to be accessible without the storage provider.
349-
// In effect everything is a shadow namespace.
362+
// There is no difference between the /Shares folder and normal nodes because the storage is not supposed to be accessible
363+
// without the storage provider. In effect everything is a shadow namespace.
350364
// To mimic the eos and owncloud driver we only allow references as children of the "/Shares" folder
365+
// FIXME: This comment should explain briefly what a reference is in this context.
351366
func (fs *Decomposedfs) CreateReference(ctx context.Context, p string, targetURI *url.URL) (err error) {
352367
ctx, span := rtrace.Provider.Tracer("reva").Start(ctx, "CreateReference")
353368
defer span.End()
@@ -368,39 +383,62 @@ func (fs *Decomposedfs) CreateReference(ctx context.Context, p string, targetURI
368383
}
369384

370385
// create Shares folder if it does not exist
371-
var n *node.Node
372-
if n, err = fs.lu.NodeFromResource(ctx, &provider.Reference{Path: fs.o.ShareFolder}); err != nil {
386+
var parentNode *node.Node
387+
var parentCreated, childCreated bool // defaults to false
388+
if parentNode, err = fs.lu.NodeFromResource(ctx, &provider.Reference{Path: fs.o.ShareFolder}); err != nil {
373389
err := errtypes.InternalError(err.Error())
374390
span.SetStatus(codes.Error, err.Error())
375391
return err
376-
} else if !n.Exists {
377-
if err = fs.tp.CreateDir(ctx, n); err != nil {
392+
} else if !parentNode.Exists {
393+
if err = fs.tp.CreateDir(ctx, parentNode); err != nil {
378394
span.SetStatus(codes.Error, err.Error())
379395
return err
380396
}
381-
}
397+
parentCreated = true
398+
}
399+
400+
var childNode *node.Node
401+
// clean up directories created here on error
402+
defer func() {
403+
if err != nil {
404+
// do not catch the error to not shadow the original error
405+
if childCreated && childNode != nil {
406+
if tmpErr := fs.tp.Delete(ctx, childNode); tmpErr != nil {
407+
appctx.GetLogger(ctx).Error().Err(tmpErr).Str("node_id", childNode.ID).Msg("Can not clean up child node after error")
408+
}
409+
}
410+
if parentCreated && parentNode != nil {
411+
if tmpErr := fs.tp.Delete(ctx, parentNode); tmpErr != nil {
412+
appctx.GetLogger(ctx).Error().Err(tmpErr).Str("node_id", parentNode.ID).Msg("Can not clean up parent node after error")
413+
}
414+
415+
}
416+
}
417+
}()
382418

383-
if n, err = n.Child(ctx, parts[1]); err != nil {
419+
if childNode, err = parentNode.Child(ctx, parts[1]); err != nil {
384420
return errtypes.InternalError(err.Error())
385421
}
386422

387-
if n.Exists {
423+
if childNode.Exists {
388424
// TODO append increasing number to mountpoint name
389425
err := errtypes.AlreadyExists(p)
390426
span.SetStatus(codes.Error, err.Error())
391427
return err
392428
}
393429

394-
if err := fs.tp.CreateDir(ctx, n); err != nil {
430+
if err := fs.tp.CreateDir(ctx, childNode); err != nil {
395431
span.SetStatus(codes.Error, err.Error())
396432
return err
397433
}
434+
childCreated = true
398435

399-
internal := n.InternalPath()
400-
if err := xattr.Set(internal, xattrs.ReferenceAttr, []byte(targetURI.String())); err != nil {
436+
internalPath := childNode.InternalPath()
437+
if err := xattr.Set(internalPath, xattrs.ReferenceAttr, []byte(targetURI.String())); err != nil {
438+
// the reference could not be set - that would result in an lost reference?
401439
err := errors.Wrapf(err, "Decomposedfs: error setting the target %s on the reference file %s",
402440
targetURI.String(),
403-
internal,
441+
internalPath,
404442
)
405443
span.SetStatus(codes.Error, err.Error())
406444
return err

pkg/storage/utils/decomposedfs/spaces.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -511,13 +511,15 @@ func (fs *Decomposedfs) createStorageSpace(ctx context.Context, spaceType, space
511511
if err != nil {
512512
if isAlreadyExists(err) {
513513
appctx.GetLogger(ctx).Debug().Err(err).Str("space", spaceID).Str("spacetype", spaceType).Msg("symlink already exists")
514+
// FIXME: is it ok to wipe this err if the symlink already exists?
515+
err = nil
514516
} else {
515517
// TODO how should we handle error cases here?
516518
appctx.GetLogger(ctx).Error().Err(err).Str("space", spaceID).Str("spacetype", spaceType).Msg("could not create symlink")
517519
}
518520
}
519521

520-
return nil
522+
return err
521523
}
522524

523525
func (fs *Decomposedfs) storageSpaceFromNode(ctx context.Context, n *node.Node, spaceType, nodePath string, canListAllSpaces bool) (*provider.StorageSpace, error) {

0 commit comments

Comments
 (0)