32 lines
1 KiB
Diff
32 lines
1 KiB
Diff
# UNDF: UNDF-2026-000001017
|
|
# juicefs-0001: Rule.CanAccess named-group scan O(G*N) -> O(G+N)
|
|
# Defect: pkg/acl/acl.go CanAccess() nested loop over caller gids * NamedGroups
|
|
# Fix: build gidSet map once (O(G)), then scan NamedGroups once with O(1) lookup
|
|
--- a/pkg/acl/acl.go
|
|
+++ b/pkg/acl/acl.go
|
|
@@ -232,14 +232,19 @@
|
|
isGrpMatched = true
|
|
}
|
|
}
|
|
+ // Build a set of the caller's group IDs so each named-group entry can be
|
|
+ // checked in O(1) rather than re-scanning gids for every named group.
|
|
+ // Previous complexity: O(G*N); fixed complexity: O(G+N).
|
|
+ gidSet := make(map[uint32]struct{}, len(gids))
|
|
for _, gid := range gids {
|
|
- for _, nGrp := range r.NamedGroups {
|
|
- if gid == nGrp.Id {
|
|
- if uint8(nGrp.Perm&r.Mask&7)&mMask == mMask {
|
|
- return true
|
|
- }
|
|
- isGrpMatched = true
|
|
+ gidSet[gid] = struct{}{}
|
|
+ }
|
|
+ for _, nGrp := range r.NamedGroups {
|
|
+ if _, ok := gidSet[nGrp.Id]; ok {
|
|
+ if uint8(nGrp.Perm&r.Mask&7)&mMask == mMask {
|
|
+ return true
|
|
}
|
|
+ isGrpMatched = true
|
|
}
|
|
}
|
|
if isGrpMatched {
|