@@ -2703,52 +2703,27 @@ func (m *dbMeta) doBatchUnlink(ctx Context, parent Ino, entries []Entry, length
27032703 info .n = * n
27042704 }
27052705
2706- filtered := entryInfos [:0 ]
2706+ filteredInfos := entryInfos [:0 ]
27072707 for i := range entryInfos {
27082708 if entryInfos [i ].e .Inode != 0 {
2709- filtered = append (filtered , entryInfos [i ])
2709+ filteredInfos = append (filteredInfos , entryInfos [i ])
27102710 }
27112711 }
2712- entryInfos = filtered
2712+ entryInfos = filteredInfos
27132713 }
27142714
2715- // Batch check if trash entries already exist to avoid duplicate hardlinks
2716- var edges []edge
2717- var idxs []int
27182715 for i := range entryInfos {
27192716 info := & entryInfos [i ]
27202717 if info .trash > 0 && info .n .Nlink > 1 {
27212718 info .trashName = m .trashEntry (parent , info .e .Inode , string (info .e .Name ))
2722- edges = append ( edges , edge {
2719+ te := edge {
27232720 Parent : info .trash ,
27242721 Name : []byte (info .trashName ),
27252722 Inode : info .e .Inode ,
27262723 Type : info .e .Type ,
2727- })
2728- idxs = append (idxs , i )
2729- }
2730- }
2731- if len (edges ) > 0 {
2732- var found []edge
2733- q := s .Table (& edge {})
2734- for i , e := range edges {
2735- if i == 0 {
2736- q = q .Where ("(parent = ? AND name = ?)" , e .Parent , e .Name )
2737- } else {
2738- q = q .Or ("(parent = ? AND name = ?)" , e .Parent , e .Name )
27392724 }
2740- }
2741- if err := q .Find (& found ); err != nil {
2742- return err
2743- }
2744- exists := make (map [string ]bool , len (found ))
2745- for _ , e := range found {
2746- exists [fmt .Sprintf ("%d:%s" , e .Parent , string (e .Name ))] = true
2747- }
2748- for i , idx := range idxs {
2749- key := fmt .Sprintf ("%d:%s" , edges [i ].Parent , string (edges [i ].Name ))
2750- if exists [key ] {
2751- entryInfos [idx ].trash = 0
2725+ if ok , err := s .Get (& te ); err == nil && ok {
2726+ info .trash = 0
27522727 }
27532728 }
27542729 }
@@ -2768,13 +2743,14 @@ func (m *dbMeta) doBatchUnlink(ctx Context, parent Ino, entries []Entry, length
27682743 continue
27692744 }
27702745 processed := seen [info .e .Inode ] + 1
2771- finalNlink := int64 (info .n .Nlink ) - int64 (processed )
2772- if finalNlink < 0 {
2773- finalNlink = 0
2774- }
2775- // If trash is enabled and this would be the last link, keep one link by moving it into trash.
2776- if info .trash > 0 && finalNlink == 0 {
2777- finalNlink = 1
2746+ var finalNlink int64
2747+ if info .trash == 0 {
2748+ finalNlink = int64 (info .n .Nlink ) - int64 (processed )
2749+ if finalNlink < 0 {
2750+ finalNlink = 0
2751+ }
2752+ } else {
2753+ finalNlink = int64 (info .n .Nlink )
27782754 }
27792755 info .lastLink = (info .trash == 0 && finalNlink == 0 )
27802756 if info .lastLink && info .e .Type == TypeFile && m .sid > 0 {
@@ -2784,129 +2760,78 @@ func (m *dbMeta) doBatchUnlink(ctx Context, parent Ino, entries []Entry, length
27842760 seen [info .e .Inode ] = processed
27852761 }
27862762
2787- trashMap := make (map [Ino ]bool )
2788- now = time .Now ().Unix ()
2789-
2790- var delEdges []edge
2791- var updNodes []node
2792- var trashEdges []edge
2793- var sustaineds []sustained
2794- var delfiles []delfile
2795- var delNodes , delSymlinks , delXattrs []Ino
2763+ trashInserted := make (map [Ino ]bool )
2764+ nowUnix := time .Now ().Unix ()
27962765
27972766 for _ , info := range entryInfos {
27982767 if info .e .Type == TypeDirectory {
27992768 continue
28002769 }
2801- delEdges = append (delEdges , edge {Parent : parent , Name : info .e .Name })
2770+ e := edge {Parent : parent , Name : info .e .Name }
2771+ if _ , err := s .Delete (& e ); err != nil {
2772+ return err
2773+ }
28022774
28032775 if info .n .Nlink > 0 {
2804- updNodes = append (updNodes , info .n )
2805- if info .trash > 0 && ! trashMap [info .e .Inode ] {
2776+ if _ , err := s .Cols ("nlink" , "ctime" , "ctimensec" , "parent" ).Update (& info .n , & node {Inode : info .n .Inode }); err != nil {
2777+ return err
2778+ }
2779+ if info .trash > 0 && ! trashInserted [info .e .Inode ] {
28062780 if info .trashName == "" {
28072781 info .trashName = m .trashEntry (parent , info .e .Inode , string (info .e .Name ))
28082782 }
2809- trashEdges = append ( trashEdges , edge {
2783+ te := edge {
28102784 Parent : info .trash ,
28112785 Name : []byte (info .trashName ),
28122786 Inode : info .e .Inode ,
28132787 Type : info .e .Type ,
2814- })
2815- trashMap [info .e .Inode ] = true
2788+ }
2789+ if err := mustInsert (s , & te ); err != nil {
2790+ return err
2791+ }
2792+ trashInserted [info .e .Inode ] = true
28162793 }
2817- recordDeletionStats (& info .n , align4K (info .n .Length ), 0 , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
2794+ entrySpace := align4K (info .n .Length )
2795+ recordDeletionStats (& info .n , entrySpace , 0 , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
28182796 } else {
28192797 switch info .e .Type {
28202798 case TypeFile :
2821- space := align4K (info .n .Length )
2799+ entrySpace := align4K (info .n .Length )
28222800 if info .opened {
2823- sustaineds = append (sustaineds , sustained {Sid : m .sid , Inode : info .e .Inode })
2824- updNodes = append (updNodes , info .n )
2825- recordDeletionStats (& info .n , space , 0 , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
2801+ if err := mustInsert (s , & sustained {Sid : m .sid , Inode : info .e .Inode }); err != nil {
2802+ return err
2803+ }
2804+ if _ , err := s .Cols ("nlink" , "ctime" , "ctimensec" ).Update (& info .n , & node {Inode : info .n .Inode }); err != nil {
2805+ return err
2806+ }
2807+ recordDeletionStats (& info .n , entrySpace , 0 , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
28262808 } else {
2827- delfiles = append (delfiles , delfile {info .e .Inode , info .n .Length , now })
2828- delNodes = append (delNodes , info .e .Inode )
2829- recordDeletionStats (& info .n , space , - space , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
2809+ if err := mustInsert (s , & delfile {info .e .Inode , info .n .Length , nowUnix }); err != nil {
2810+ return err
2811+ }
2812+ if _ , err := s .Delete (& node {Inode : info .e .Inode }); err != nil {
2813+ return err
2814+ }
2815+ recordDeletionStats (& info .n , entrySpace , - entrySpace , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
28302816 }
28312817 case TypeSymlink :
2832- delSymlinks = append (delSymlinks , info .e .Inode )
2818+ if _ , err := s .Delete (& symlink {Inode : info .e .Inode }); err != nil {
2819+ return err
2820+ }
28332821 fallthrough
28342822 default :
2835- delNodes = append (delNodes , info .e .Inode )
2823+ if _ , err := s .Delete (& node {Inode : info .e .Inode }); err != nil {
2824+ return err
2825+ }
28362826 if info .e .Type != TypeFile {
2837- recordDeletionStats (& info .n , 0 , 0 , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
2827+ entrySpace := align4K (0 )
2828+ recordDeletionStats (& info .n , entrySpace , - entrySpace , & totalLength , & totalSpace , & totalInodes , userGroupQuotas , trash )
28382829 }
28392830 }
2840- delXattrs = append (delXattrs , info .e .Inode )
2841- }
2842- }
2843-
2844- // Batch delete edges
2845- if len (delEdges ) > 0 {
2846- q := s .Table (& edge {})
2847- for i , e := range delEdges {
2848- if i == 0 {
2849- q = q .Where ("(parent = ? AND name = ?)" , e .Parent , e .Name )
2850- } else {
2851- q = q .Or ("(parent = ? AND name = ?)" , e .Parent , e .Name )
2831+ if _ , err := s .Delete (& xattr {Inode : info .e .Inode }); err != nil {
2832+ return err
28522833 }
28532834 }
2854- if _ , err := q .Delete (& edge {}); err != nil {
2855- return err
2856- }
2857- }
2858-
2859- // Batch update nodes
2860- for _ , n := range updNodes {
2861- if _ , err := s .Cols ("nlink" , "ctime" , "ctimensec" , "parent" ).Update (& n , & node {Inode : n .Inode }); err != nil {
2862- return err
2863- }
2864- }
2865-
2866- // Batch inserts
2867- if len (trashEdges ) > 0 {
2868- items := make ([]interface {}, len (trashEdges ))
2869- for i := range trashEdges {
2870- items [i ] = & trashEdges [i ]
2871- }
2872- if err := mustInsert (s , items ... ); err != nil {
2873- return err
2874- }
2875- }
2876- if len (sustaineds ) > 0 {
2877- items := make ([]interface {}, len (sustaineds ))
2878- for i := range sustaineds {
2879- items [i ] = & sustaineds [i ]
2880- }
2881- if err := mustInsert (s , items ... ); err != nil {
2882- return err
2883- }
2884- }
2885- if len (delfiles ) > 0 {
2886- items := make ([]interface {}, len (delfiles ))
2887- for i := range delfiles {
2888- items [i ] = & delfiles [i ]
2889- }
2890- if err := mustInsert (s , items ... ); err != nil {
2891- return err
2892- }
2893- }
2894-
2895- // Batch deletes
2896- if len (delNodes ) > 0 {
2897- if _ , err := s .In ("inode" , delNodes ).Delete (& node {}); err != nil {
2898- return err
2899- }
2900- }
2901- if len (delSymlinks ) > 0 {
2902- if _ , err := s .In ("inode" , delSymlinks ).Delete (& symlink {}); err != nil {
2903- return err
2904- }
2905- }
2906- if len (delXattrs ) > 0 {
2907- if _ , err := s .In ("inode" , delXattrs ).Delete (& xattr {}); err != nil {
2908- return err
2909- }
29102835 }
29112836
29122837 for _ , info := range entryInfos {
0 commit comments