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: list: extract common code for insertion

To prepare for a new cursor API that has the ability to insert elements
into the list, extract the common code needed for this operation into a
new `insert_inner` method.

Both `push_back` and `push_front` are updated to use the new function.

Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20250210-cursor-between-v7-1-36f0215181ed@google.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

authored by

Alice Ryhl and committed by
Miguel Ojeda
998c6573 6ad64bf9

+32 -38
+32 -38
rust/kernel/list.rs
··· 245 245 self.first.is_null() 246 246 } 247 247 248 - /// Add the provided item to the back of the list. 249 - pub fn push_back(&mut self, item: ListArc<T, ID>) { 248 + /// Inserts `item` before `next` in the cycle. 249 + /// 250 + /// Returns a pointer to the newly inserted element. Never changes `self.first` unless the list 251 + /// is empty. 252 + /// 253 + /// # Safety 254 + /// 255 + /// * `next` must be an element in this list or null. 256 + /// * if `next` is null, then the list must be empty. 257 + unsafe fn insert_inner( 258 + &mut self, 259 + item: ListArc<T, ID>, 260 + next: *mut ListLinksFields, 261 + ) -> *mut ListLinksFields { 250 262 let raw_item = ListArc::into_raw(item); 251 263 // SAFETY: 252 264 // * We just got `raw_item` from a `ListArc`, so it's in an `Arc`. ··· 271 259 // SAFETY: We have not yet called `post_remove`, so `list_links` is still valid. 272 260 let item = unsafe { ListLinks::fields(list_links) }; 273 261 274 - if self.first.is_null() { 275 - self.first = item; 262 + // Check if the list is empty. 263 + if next.is_null() { 276 264 // SAFETY: The caller just gave us ownership of these fields. 277 265 // INVARIANT: A linked list with one item should be cyclic. 278 266 unsafe { 279 267 (*item).next = item; 280 268 (*item).prev = item; 281 269 } 270 + self.first = item; 282 271 } else { 283 - let next = self.first; 284 272 // SAFETY: By the type invariant, this pointer is valid or null. We just checked that 285 273 // it's not null, so it must be valid. 286 274 let prev = unsafe { (*next).prev }; ··· 294 282 (*next).prev = item; 295 283 } 296 284 } 285 + 286 + item 287 + } 288 + 289 + /// Add the provided item to the back of the list. 290 + pub fn push_back(&mut self, item: ListArc<T, ID>) { 291 + // SAFETY: 292 + // * `self.first` is null or in the list. 293 + // * `self.first` is only null if the list is empty. 294 + unsafe { self.insert_inner(item, self.first) }; 297 295 } 298 296 299 297 /// Add the provided item to the front of the list. 300 298 pub fn push_front(&mut self, item: ListArc<T, ID>) { 301 - let raw_item = ListArc::into_raw(item); 302 299 // SAFETY: 303 - // * We just got `raw_item` from a `ListArc`, so it's in an `Arc`. 304 - // * If this requirement is violated, then the previous caller of `prepare_to_insert` 305 - // violated the safety requirement that they can't give up ownership of the `ListArc` 306 - // until they call `post_remove`. 307 - // * We own the `ListArc`. 308 - // * Removing items] from this list is always done using `remove_internal_inner`, which 309 - // calls `post_remove` before giving up ownership. 310 - let list_links = unsafe { T::prepare_to_insert(raw_item) }; 311 - // SAFETY: We have not yet called `post_remove`, so `list_links` is still valid. 312 - let item = unsafe { ListLinks::fields(list_links) }; 300 + // * `self.first` is null or in the list. 301 + // * `self.first` is only null if the list is empty. 302 + let new_elem = unsafe { self.insert_inner(item, self.first) }; 313 303 314 - if self.first.is_null() { 315 - // SAFETY: The caller just gave us ownership of these fields. 316 - // INVARIANT: A linked list with one item should be cyclic. 317 - unsafe { 318 - (*item).next = item; 319 - (*item).prev = item; 320 - } 321 - } else { 322 - let next = self.first; 323 - // SAFETY: We just checked that `next` is non-null. 324 - let prev = unsafe { (*next).prev }; 325 - // SAFETY: Pointers in a linked list are never dangling, and the caller just gave us 326 - // ownership of the fields on `item`. 327 - // INVARIANT: This correctly inserts `item` between `prev` and `next`. 328 - unsafe { 329 - (*item).next = next; 330 - (*item).prev = prev; 331 - (*prev).next = item; 332 - (*next).prev = item; 333 - } 334 - } 335 - self.first = item; 304 + // INVARIANT: `new_elem` is in the list because we just inserted it. 305 + self.first = new_elem; 336 306 } 337 307 338 308 /// Removes the last item from this list.