@@ -817,26 +817,40 @@ func (t *Tree) createNode(n *node.Node, owner *userpb.UserId) (err error) {
817
817
return n .WriteAllNodeMetadata (owner )
818
818
}
819
819
820
+ // readTrashLink returns nodeID and timestamp
821
+ func readTrashLink (path string ) (string , string , error ) {
822
+ link , err := os .Readlink (path )
823
+ if err != nil {
824
+ return "" , "" , err
825
+ }
826
+ // ../../../../../nodes/e5/6c/75/a8/-d235-4cbb-8b4e-48b6fd0f2094.T.2022-02-16T14:38:11.769917408Z
827
+ // TODO use filepath.Separator to support windows
828
+ link = strings .ReplaceAll (link , "/" , "" )
829
+ // ..........nodese56c75a8-d235-4cbb-8b4e-48b6fd0f2094.T.2022-02-16T14:38:11.769917408Z
830
+ if link [0 :15 ] != "..........nodes" || link [51 :54 ] != ".T." {
831
+ return "" , "" , errtypes .InternalError ("malformed trash link" )
832
+ }
833
+ return link [15 :51 ], link [54 :], nil
834
+ }
835
+
820
836
// TODO refactor the returned params into Node properties? would make all the path transformations go away...
821
837
func (t * Tree ) readRecycleItem (ctx context.Context , spaceID , key , path string ) (recycleNode * node.Node , trashItem string , deletedNodePath string , origin string , err error ) {
822
838
if key == "" {
823
839
return nil , "" , "" , "" , errtypes .InternalError ("key is empty" )
824
840
}
825
841
826
- trashItem = filepath .Join (t .lookup .InternalRoot (), "trash " , spaceID , key , path )
842
+ trashItem = filepath .Join (t .lookup .InternalRoot (), "spaces " , Pathify ( spaceID , 1 , 2 ), "trash" , Pathify ( key , 4 , 2 ) , path )
827
843
828
- var link string
829
- link , err = os .Readlink (trashItem )
844
+ nodeID , timeSuffix , err := readTrashLink (trashItem )
830
845
if err != nil {
831
846
appctx .GetLogger (ctx ).Error ().Err (err ).Str ("trashItem" , trashItem ).Msg ("error reading trash link" )
832
847
return
833
848
}
834
849
835
- var attrStr string
836
- trashNodeID := filepath .Base (link )
837
- deletedNodePath = t .lookup .InternalPath (spaceID , trashNodeID )
850
+ deletedNodePath = t .lookup .InternalPath (spaceID , nodeID ) + node .TrashIDDelimiter + timeSuffix
838
851
839
852
owner := & userpb.UserId {}
853
+ var attrStr string
840
854
// lookup ownerId in extended attributes
841
855
if attrStr , err = xattrs .Get (deletedNodePath , xattrs .OwnerIDAttr ); err == nil {
842
856
owner .OpaqueId = attrStr
@@ -856,7 +870,7 @@ func (t *Tree) readRecycleItem(ctx context.Context, spaceID, key, path string) (
856
870
return
857
871
}
858
872
859
- recycleNode = node .New (spaceID , trashNodeID , "" , "" , 0 , "" , owner , t .lookup )
873
+ recycleNode = node .New (spaceID , nodeID , "" , "" , 0 , "" , owner , t .lookup )
860
874
// lookup blobID in extended attributes
861
875
if attrStr , err = xattrs .Get (deletedNodePath , xattrs .BlobIDAttr ); err == nil {
862
876
recycleNode .BlobID = attrStr
@@ -879,37 +893,28 @@ func (t *Tree) readRecycleItem(ctx context.Context, spaceID, key, path string) (
879
893
}
880
894
881
895
// look up space root from the trashed node
882
- err = recycleNode .FindStorageSpaceRoot ()
883
-
884
- if path == "" || path == "/" {
885
- parts := strings .SplitN (filepath .Base (link ), node .TrashIDDelimiter , 2 )
886
- if len (parts ) != 2 {
887
- appctx .GetLogger (ctx ).Error ().Err (err ).Str ("trashItem" , trashItem ).Interface ("parts" , parts ).Msg ("malformed trash link" )
888
- return
889
- }
890
- // update the node id, drop the `.T.{timestamp}` suffix
891
- recycleNode .ID = parts [0 ]
896
+ if err = recycleNode .FindStorageSpaceRoot (); err != nil {
897
+ return
892
898
}
893
899
894
900
// get origin node, is relative to space root
895
901
origin = "/"
896
902
897
903
deletedNodeRootPath := deletedNodePath
898
904
if path != "" && path != "/" {
899
- trashItemRoot := filepath .Join (t .lookup .InternalRoot (), "trash" , spaceID , key )
900
- var rootLink string
901
- rootLink , err = os .Readlink (trashItemRoot )
905
+ trashItemRoot := filepath .Join (t .lookup .InternalRoot (), "spaces" , Pathify (spaceID , 1 , 2 ), "trash" , Pathify (key , 4 , 2 ))
906
+ nodeID , _ , err = readTrashLink (trashItemRoot )
902
907
if err != nil {
903
908
appctx .GetLogger (ctx ).Error ().Err (err ).Str ("trashItem" , trashItem ).Msg ("error reading trash link" )
904
909
return
905
910
}
906
- deletedNodeRootPath = t .lookup .InternalPath (spaceID , filepath . Base ( rootLink ) )
911
+ deletedNodeRootPath = t .lookup .InternalPath (spaceID , nodeID )
907
912
}
908
913
// lookup origin path in extended attributes
909
914
if attrStr , err = xattrs .Get (deletedNodeRootPath , xattrs .TrashOriginAttr ); err == nil {
910
915
origin = filepath .Join (attrStr , path )
911
916
} else {
912
- log .Error ().Err (err ).Str ("trashItem" , trashItem ).Str ("link" , link ). Str ( " deletedNodePath" , deletedNodePath ).Msg ("could not read origin path, restoring to /" )
917
+ log .Error ().Err (err ).Str ("trashItem" , trashItem ).Str ("deletedNodePath" , deletedNodePath ).Msg ("could not read origin path, restoring to /" )
913
918
}
914
919
915
920
return
0 commit comments