Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: rbtree: reduce unsafe blocks on pointer derefs

Refactors parts of the get() and find_best_match()
traversal logic to minimize the scope of unsafe blocks
and avoid duplicating same safety comments.

One of the removed comments was also misleading:

// SAFETY: `node` is a non-null node...
Ordering::Equal => return Some(unsafe { &(*this).value }),

as `node` should have been `this`.

No functional changes intended; this is purely a safety
improvement that reduces the amount of unsafe blocks
while keeping all invariants intact.

[ Alice writes:

"One consequence of creating a &_ to the bindings::rb_node struct means
that we assert immutability for the entire struct and not just the
rb_left/rb_right fields, but I have verified that this is ok."

- Miguel ]

Signed-off-by: Onur Özkan <work@onurozkan.dev>
Reviewed-by: Charalampos Mitrodimas <charmitro@posteo.net>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20251113144547.502-1-work@onurozkan.dev
[ Reworded title and replaced `cursor_lower_bound()` with
`find_best_match()` in message. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

authored by

Onur Özkan and committed by
Miguel Ojeda
2ad6c5cd 6c37b684

+15 -12
+15 -12
rust/kernel/rbtree.rs
··· 414 414 // SAFETY: By the type invariant of `Self`, all non-null `rb_node` pointers stored in `self` 415 415 // point to the links field of `Node<K, V>` objects. 416 416 let this = unsafe { container_of!(node, Node<K, V>, links) }; 417 + 417 418 // SAFETY: `this` is a non-null node so it is valid by the type invariants. 418 - node = match key.cmp(unsafe { &(*this).key }) { 419 - // SAFETY: `node` is a non-null node so it is valid by the type invariants. 420 - Ordering::Less => unsafe { (*node).rb_left }, 421 - // SAFETY: `node` is a non-null node so it is valid by the type invariants. 422 - Ordering::Greater => unsafe { (*node).rb_right }, 423 - // SAFETY: `node` is a non-null node so it is valid by the type invariants. 424 - Ordering::Equal => return Some(unsafe { &(*this).value }), 419 + let this_ref = unsafe { &*this }; 420 + 421 + // SAFETY: `node` is a non-null node so it is valid by the type invariants. 422 + let node_ref = unsafe { &*node }; 423 + 424 + node = match key.cmp(&this_ref.key) { 425 + Ordering::Less => node_ref.rb_left, 426 + Ordering::Greater => node_ref.rb_right, 427 + Ordering::Equal => return Some(&this_ref.value), 425 428 } 426 429 } 427 430 None ··· 501 498 let this = unsafe { container_of!(node, Node<K, V>, links) }; 502 499 // SAFETY: `this` is a non-null node so it is valid by the type invariants. 503 500 let this_key = unsafe { &(*this).key }; 501 + 504 502 // SAFETY: `node` is a non-null node so it is valid by the type invariants. 505 - let left_child = unsafe { (*node).rb_left }; 506 - // SAFETY: `node` is a non-null node so it is valid by the type invariants. 507 - let right_child = unsafe { (*node).rb_right }; 503 + let node_ref = unsafe { &*node }; 504 + 508 505 match key.cmp(this_key) { 509 506 Ordering::Equal => { 510 507 // SAFETY: `this` is a non-null node so it is valid by the type invariants. ··· 512 509 break; 513 510 } 514 511 Ordering::Greater => { 515 - node = right_child; 512 + node = node_ref.rb_right; 516 513 } 517 514 Ordering::Less => { 518 515 let is_better_match = match best_key { ··· 524 521 // SAFETY: `this` is a non-null node so it is valid by the type invariants. 525 522 best_links = Some(unsafe { NonNull::new_unchecked(&mut (*this).links) }); 526 523 } 527 - node = left_child; 524 + node = node_ref.rb_left; 528 525 } 529 526 }; 530 527 }