Skip to content

Commit

Permalink
fix restore
Browse files Browse the repository at this point in the history
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
  • Loading branch information
butonic committed Feb 16, 2022
1 parent 15db9ad commit e60fb6b
Showing 1 changed file with 27 additions and 22 deletions.
49 changes: 27 additions & 22 deletions pkg/storage/utils/decomposedfs/tree/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -817,26 +817,40 @@ func (t *Tree) createNode(n *node.Node, owner *userpb.UserId) (err error) {
return n.WriteAllNodeMetadata(owner)
}

// readTrashLink returns nodeID and timestamp
func readTrashLink(path string) (string, string, error) {
link, err := os.Readlink(path)
if err != nil {
return "", "", err
}
// ../../../../../nodes/e5/6c/75/a8/-d235-4cbb-8b4e-48b6fd0f2094.T.2022-02-16T14:38:11.769917408Z
// TODO use filepath.Separator to support windows
link = strings.ReplaceAll(link, "/", "")
// ..........nodese56c75a8-d235-4cbb-8b4e-48b6fd0f2094.T.2022-02-16T14:38:11.769917408Z
if link[0:15] != "..........nodes" || link[51:54] != ".T." {
return "", "", errtypes.InternalError("malformed trash link")
}
return link[15:51], link[54:], nil
}

// TODO refactor the returned params into Node properties? would make all the path transformations go away...
func (t *Tree) readRecycleItem(ctx context.Context, spaceID, key, path string) (recycleNode *node.Node, trashItem string, deletedNodePath string, origin string, err error) {
if key == "" {
return nil, "", "", "", errtypes.InternalError("key is empty")
}

trashItem = filepath.Join(t.lookup.InternalRoot(), "trash", spaceID, key, path)
trashItem = filepath.Join(t.lookup.InternalRoot(), "spaces", Pathify(spaceID, 1, 2), "trash", Pathify(key, 4, 2), path)

var link string
link, err = os.Readlink(trashItem)
nodeID, timeSuffix, err := readTrashLink(trashItem)
if err != nil {
appctx.GetLogger(ctx).Error().Err(err).Str("trashItem", trashItem).Msg("error reading trash link")
return
}

var attrStr string
trashNodeID := filepath.Base(link)
deletedNodePath = t.lookup.InternalPath(spaceID, trashNodeID)
deletedNodePath = t.lookup.InternalPath(spaceID, nodeID) + node.TrashIDDelimiter + timeSuffix

owner := &userpb.UserId{}
var attrStr string
// lookup ownerId in extended attributes
if attrStr, err = xattrs.Get(deletedNodePath, xattrs.OwnerIDAttr); err == nil {
owner.OpaqueId = attrStr
Expand All @@ -856,7 +870,7 @@ func (t *Tree) readRecycleItem(ctx context.Context, spaceID, key, path string) (
return
}

recycleNode = node.New(spaceID, trashNodeID, "", "", 0, "", owner, t.lookup)
recycleNode = node.New(spaceID, nodeID, "", "", 0, "", owner, t.lookup)
// lookup blobID in extended attributes
if attrStr, err = xattrs.Get(deletedNodePath, xattrs.BlobIDAttr); err == nil {
recycleNode.BlobID = attrStr
Expand All @@ -879,37 +893,28 @@ func (t *Tree) readRecycleItem(ctx context.Context, spaceID, key, path string) (
}

// look up space root from the trashed node
err = recycleNode.FindStorageSpaceRoot()

if path == "" || path == "/" {
parts := strings.SplitN(filepath.Base(link), node.TrashIDDelimiter, 2)
if len(parts) != 2 {
appctx.GetLogger(ctx).Error().Err(err).Str("trashItem", trashItem).Interface("parts", parts).Msg("malformed trash link")
return
}
// update the node id, drop the `.T.{timestamp}` suffix
recycleNode.ID = parts[0]
if err = recycleNode.FindStorageSpaceRoot(); err != nil {
return
}

// get origin node, is relative to space root
origin = "/"

deletedNodeRootPath := deletedNodePath
if path != "" && path != "/" {
trashItemRoot := filepath.Join(t.lookup.InternalRoot(), "trash", spaceID, key)
var rootLink string
rootLink, err = os.Readlink(trashItemRoot)
trashItemRoot := filepath.Join(t.lookup.InternalRoot(), "spaces", Pathify(spaceID, 1, 2), "trash", Pathify(key, 4, 2))
nodeID, _, err = readTrashLink(trashItemRoot)
if err != nil {
appctx.GetLogger(ctx).Error().Err(err).Str("trashItem", trashItem).Msg("error reading trash link")
return
}
deletedNodeRootPath = t.lookup.InternalPath(spaceID, filepath.Base(rootLink))
deletedNodeRootPath = t.lookup.InternalPath(spaceID, nodeID)
}
// lookup origin path in extended attributes
if attrStr, err = xattrs.Get(deletedNodeRootPath, xattrs.TrashOriginAttr); err == nil {
origin = filepath.Join(attrStr, path)
} else {
log.Error().Err(err).Str("trashItem", trashItem).Str("link", link).Str("deletedNodePath", deletedNodePath).Msg("could not read origin path, restoring to /")
log.Error().Err(err).Str("trashItem", trashItem).Str("deletedNodePath", deletedNodePath).Msg("could not read origin path, restoring to /")
}

return
Expand Down

0 comments on commit e60fb6b

Please sign in to comment.