Skip to main content

kernel/
bitmap.rs

1// SPDX-License-Identifier: GPL-2.0
2
3// Copyright (C) 2025 Google LLC.
4
5//! Rust API for bitmap.
6//!
7//! C headers: [`include/linux/bitmap.h`](srctree/include/linux/bitmap.h).
8
9use crate::alloc::{AllocError, Flags};
10use crate::bindings;
11#[cfg(not(CONFIG_RUST_BITMAP_HARDENED))]
12use crate::pr_err;
13use core::ptr::NonNull;
14
15/// Represents a C bitmap. Wraps underlying C bitmap API.
16///
17/// # Invariants
18///
19/// Must reference a `[c_ulong]` long enough to fit `data.len()` bits.
20/// Must not be longer than [`i32::MAX`] bits, so offsets and lengths used with
21/// [`Bitmap`] functions fit in the `int` and `unsigned int` arguments of the C bitmap API.
22/// This also matches [`BitmapVec::MAX_LEN`].
23#[cfg_attr(CONFIG_64BIT, repr(align(8)))]
24#[cfg_attr(not(CONFIG_64BIT), repr(align(4)))]
25pub struct Bitmap {
26    data: [()],
27}
28
29macro_rules! bitmap_assert {
30    ($cond:expr, $($arg:tt)+) => {
31        #[cfg(CONFIG_RUST_BITMAP_HARDENED)]
32        assert!($cond, $($arg)*);
33    }
34}
35
36macro_rules! bitmap_assert_return {
37    ($cond:expr, $($arg:tt)+) => {
38        #[cfg(CONFIG_RUST_BITMAP_HARDENED)]
39        assert!($cond, $($arg)*);
40
41        #[cfg(not(CONFIG_RUST_BITMAP_HARDENED))]
42        if !($cond) {
43            pr_err!($($arg)*);
44            return
45        }
46    }
47}
48
49impl Bitmap {
50    /// Borrows a C bitmap.
51    ///
52    /// # Panics
53    ///
54    /// Panics if CONFIG_RUST_BITMAP_HARDENED is enabled and `nbits` exceeds [`i32::MAX`].
55    ///
56    /// # Safety
57    ///
58    /// * `ptr` holds a non-null address of an initialized array of `unsigned long`
59    ///   that is large enough to hold `nbits` bits.
60    /// * `nbits` must not exceed [`i32::MAX`].
61    /// * the array must not be freed for the lifetime of this [`Bitmap`]
62    /// * concurrent access only happens through atomic operations
63    pub unsafe fn from_raw<'a>(ptr: *const usize, nbits: usize) -> &'a Bitmap {
64        bitmap_assert!(
65            nbits <= i32::MAX as usize,
66            "`nbits` must be <= {}, was {}",
67            i32::MAX,
68            nbits
69        );
70        let data: *const [()] = core::ptr::slice_from_raw_parts(ptr.cast(), nbits);
71        // INVARIANT: `data` references an initialized array that can hold `nbits` bits.
72        // INVARIANT: The caller guarantees that `nbits` does not exceed `i32::MAX`.
73        // SAFETY:
74        // The caller guarantees that `data` (derived from `ptr` and `nbits`)
75        // points to a valid, initialized, and appropriately sized memory region
76        // that will not be freed for the lifetime 'a.
77        // We are casting `*const [()]` to `*const Bitmap`. The `Bitmap`
78        // struct is a ZST with a `data: [()]` field. This means its layout
79        // is compatible with a slice of `()`, and effectively it's a "thin pointer"
80        // (its size is 0 and alignment is 1). The `slice_from_raw_parts`
81        // function correctly encodes the length (number of bits, not elements)
82        // into the metadata of the fat pointer. Therefore, dereferencing this
83        // pointer as `&Bitmap` is safe given the caller's guarantees.
84        unsafe { &*(data as *const Bitmap) }
85    }
86
87    /// Borrows a C bitmap exclusively.
88    ///
89    /// # Panics
90    ///
91    /// Panics if CONFIG_RUST_BITMAP_HARDENED is enabled and `nbits` exceeds [`i32::MAX`].
92    ///
93    /// # Safety
94    ///
95    /// * `ptr` holds a non-null address of an initialized array of `unsigned long`
96    ///   that is large enough to hold `nbits` bits.
97    /// * `nbits` must not exceed [`i32::MAX`].
98    /// * the array must not be freed for the lifetime of this [`Bitmap`]
99    /// * no concurrent access may happen.
100    pub unsafe fn from_raw_mut<'a>(ptr: *mut usize, nbits: usize) -> &'a mut Bitmap {
101        bitmap_assert!(
102            nbits <= i32::MAX as usize,
103            "`nbits` must be <= {}, was {}",
104            i32::MAX,
105            nbits
106        );
107        let data: *mut [()] = core::ptr::slice_from_raw_parts_mut(ptr.cast(), nbits);
108        // INVARIANT: `data` references an initialized array that can hold `nbits` bits.
109        // INVARIANT: The caller guarantees that `nbits` does not exceed `i32::MAX`.
110        // SAFETY:
111        // The caller guarantees that `data` (derived from `ptr` and `nbits`)
112        // points to a valid, initialized, and appropriately sized memory region
113        // that will not be freed for the lifetime 'a.
114        // Furthermore, the caller guarantees no concurrent access will happen,
115        // which upholds the exclusivity requirement for a mutable reference.
116        // Similar to `from_raw`, casting `*mut [()]` to `*mut Bitmap` is
117        // safe because `Bitmap` is a ZST with a `data: [()]` field,
118        // making its layout compatible with a slice of `()`.
119        unsafe { &mut *(data as *mut Bitmap) }
120    }
121
122    /// Returns a raw pointer to the backing [`Bitmap`].
123    pub fn as_ptr(&self) -> *const usize {
124        core::ptr::from_ref::<Bitmap>(self).cast::<usize>()
125    }
126
127    /// Returns a mutable raw pointer to the backing [`Bitmap`].
128    pub fn as_mut_ptr(&mut self) -> *mut usize {
129        core::ptr::from_mut::<Bitmap>(self).cast::<usize>()
130    }
131
132    /// Returns length of this [`Bitmap`].
133    #[expect(clippy::len_without_is_empty)]
134    pub fn len(&self) -> usize {
135        self.data.len()
136    }
137}
138
139/// Holds either a pointer to array of `unsigned long` or a small bitmap.
140#[repr(C)]
141union BitmapRepr {
142    bitmap: usize,
143    ptr: NonNull<usize>,
144}
145
146/// Represents an owned bitmap.
147///
148/// Wraps underlying C bitmap API. See [`Bitmap`] for available
149/// methods.
150///
151/// # Examples
152///
153/// Basic usage
154///
155/// ```
156/// use kernel::alloc::flags::GFP_KERNEL;
157/// use kernel::bitmap::BitmapVec;
158///
159/// let mut b = BitmapVec::new(16, GFP_KERNEL)?;
160///
161/// assert_eq!(16, b.len());
162/// for i in 0..16 {
163///     if i % 4 == 0 {
164///       b.set_bit(i);
165///     }
166/// }
167/// assert_eq!(Some(0), b.next_bit(0));
168/// assert_eq!(Some(1), b.next_zero_bit(0));
169/// assert_eq!(Some(4), b.next_bit(1));
170/// assert_eq!(Some(5), b.next_zero_bit(4));
171/// assert_eq!(Some(12), b.last_bit());
172/// # Ok::<(), Error>(())
173/// ```
174///
175/// # Invariants
176///
177/// * `nbits` is `<= MAX_LEN`.
178/// * if `nbits <= MAX_INLINE_LEN`, then `repr` is a `usize`.
179/// * otherwise, `repr` holds a non-null pointer to an initialized
180///   array of `unsigned long` that is large enough to hold `nbits` bits.
181pub struct BitmapVec {
182    /// Representation of bitmap.
183    repr: BitmapRepr,
184    /// Length of this bitmap. Must be `<= MAX_LEN`.
185    nbits: usize,
186}
187
188impl core::ops::Deref for BitmapVec {
189    type Target = Bitmap;
190
191    fn deref(&self) -> &Bitmap {
192        let ptr = if self.nbits <= BitmapVec::MAX_INLINE_LEN {
193            // SAFETY: Bitmap is represented inline.
194            #[allow(unused_unsafe, reason = "Safe since Rust 1.92.0")]
195            unsafe {
196                core::ptr::addr_of!(self.repr.bitmap)
197            }
198        } else {
199            // SAFETY: Bitmap is represented as array of `unsigned long`.
200            unsafe { self.repr.ptr.as_ptr() }
201        };
202
203        // SAFETY: We got the right pointer and invariants of [`Bitmap`] hold.
204        // An inline bitmap is treated like an array with single element.
205        unsafe { Bitmap::from_raw(ptr, self.nbits) }
206    }
207}
208
209impl core::ops::DerefMut for BitmapVec {
210    fn deref_mut(&mut self) -> &mut Bitmap {
211        let ptr = if self.nbits <= BitmapVec::MAX_INLINE_LEN {
212            // SAFETY: Bitmap is represented inline.
213            #[allow(unused_unsafe, reason = "Safe since Rust 1.92.0")]
214            unsafe {
215                core::ptr::addr_of_mut!(self.repr.bitmap)
216            }
217        } else {
218            // SAFETY: Bitmap is represented as array of `unsigned long`.
219            unsafe { self.repr.ptr.as_ptr() }
220        };
221
222        // SAFETY: We got the right pointer and invariants of [`BitmapVec`] hold.
223        // An inline bitmap is treated like an array with single element.
224        unsafe { Bitmap::from_raw_mut(ptr, self.nbits) }
225    }
226}
227
228/// Enable ownership transfer to other threads.
229///
230/// SAFETY: We own the underlying bitmap representation.
231unsafe impl Send for BitmapVec {}
232
233/// Enable unsynchronized concurrent access to [`BitmapVec`] through shared references.
234///
235/// SAFETY: `deref()` will return a reference to a [`Bitmap`]. Its methods
236/// take immutable references are either atomic or read-only.
237unsafe impl Sync for BitmapVec {}
238
239impl Drop for BitmapVec {
240    fn drop(&mut self) {
241        if self.nbits <= BitmapVec::MAX_INLINE_LEN {
242            return;
243        }
244        // SAFETY: `self.ptr` was returned by the C `bitmap_zalloc`.
245        //
246        // INVARIANT: there is no other use of the `self.ptr` after this
247        // call and the value is being dropped so the broken invariant is
248        // not observable on function exit.
249        unsafe { bindings::bitmap_free(self.repr.ptr.as_ptr()) };
250    }
251}
252
253impl BitmapVec {
254    /// The maximum possible length of a `BitmapVec`.
255    pub const MAX_LEN: usize = i32::MAX as usize;
256
257    /// The maximum length that uses the inline representation.
258    pub const MAX_INLINE_LEN: usize = usize::BITS as usize;
259
260    /// Construct a longest possible inline [`BitmapVec`].
261    #[inline]
262    pub fn new_inline() -> Self {
263        // INVARIANT: `nbits <= MAX_INLINE_LEN`, so an inline bitmap is the right repr.
264        BitmapVec {
265            repr: BitmapRepr { bitmap: 0 },
266            nbits: BitmapVec::MAX_INLINE_LEN,
267        }
268    }
269
270    /// Constructs a new [`BitmapVec`].
271    ///
272    /// Fails with [`AllocError`] when the [`BitmapVec`] could not be allocated. This
273    /// includes the case when `nbits` is greater than `MAX_LEN`.
274    #[inline]
275    pub fn new(nbits: usize, flags: Flags) -> Result<Self, AllocError> {
276        if nbits <= BitmapVec::MAX_INLINE_LEN {
277            return Ok(BitmapVec {
278                repr: BitmapRepr { bitmap: 0 },
279                nbits,
280            });
281        }
282        if nbits > Self::MAX_LEN {
283            return Err(AllocError);
284        }
285        let nbits_u32 = u32::try_from(nbits).unwrap();
286        // SAFETY: `MAX_INLINE_LEN < nbits` and `nbits <= MAX_LEN`.
287        let ptr = unsafe { bindings::bitmap_zalloc(nbits_u32, flags.as_raw()) };
288        let ptr = NonNull::new(ptr).ok_or(AllocError)?;
289        // INVARIANT: `ptr` returned by C `bitmap_zalloc` and `nbits` checked.
290        Ok(BitmapVec {
291            repr: BitmapRepr { ptr },
292            nbits,
293        })
294    }
295
296    /// Returns length of this [`Bitmap`].
297    #[allow(clippy::len_without_is_empty)]
298    #[inline]
299    pub fn len(&self) -> usize {
300        self.nbits
301    }
302
303    /// Fills this `Bitmap` with random bits.
304    #[cfg(CONFIG_FIND_BIT_BENCHMARK_RUST)]
305    pub fn fill_random(&mut self) {
306        // SAFETY: `self.as_mut_ptr` points to either an array of the
307        // appropriate length or one usize.
308        unsafe {
309            bindings::get_random_bytes(
310                self.as_mut_ptr().cast::<ffi::c_void>(),
311                usize::div_ceil(self.nbits, bindings::BITS_PER_LONG as usize)
312                    * bindings::BITS_PER_LONG as usize
313                    / 8,
314            );
315        }
316    }
317}
318
319impl Bitmap {
320    /// Set bit with index `index`.
321    ///
322    /// ATTENTION: `set_bit` is non-atomic, which differs from the naming
323    /// convention in C code. The corresponding C function is `__set_bit`.
324    ///
325    /// If CONFIG_RUST_BITMAP_HARDENED is not enabled and `index` is greater than
326    /// or equal to `self.nbits`, does nothing.
327    ///
328    /// # Panics
329    ///
330    /// Panics if CONFIG_RUST_BITMAP_HARDENED is enabled and `index` is greater than
331    /// or equal to `self.nbits`.
332    #[inline]
333    pub fn set_bit(&mut self, index: usize) {
334        bitmap_assert_return!(
335            index < self.len(),
336            "Bit `index` must be < {}, was {}",
337            self.len(),
338            index
339        );
340        // SAFETY: Bit `index` is within bounds.
341        unsafe { bindings::__set_bit(index, self.as_mut_ptr()) };
342    }
343
344    /// Set bit with index `index`, atomically.
345    ///
346    /// This is a relaxed atomic operation (no implied memory barriers).
347    ///
348    /// ATTENTION: The naming convention differs from C, where the corresponding
349    /// function is called `set_bit`.
350    ///
351    /// If CONFIG_RUST_BITMAP_HARDENED is not enabled and `index` is greater than
352    /// or equal to `self.len()`, does nothing.
353    ///
354    /// # Panics
355    ///
356    /// Panics if CONFIG_RUST_BITMAP_HARDENED is enabled and `index` is greater than
357    /// or equal to `self.len()`.
358    #[inline]
359    pub fn set_bit_atomic(&self, index: usize) {
360        bitmap_assert_return!(
361            index < self.len(),
362            "Bit `index` must be < {}, was {}",
363            self.len(),
364            index
365        );
366        // SAFETY: `index` is within bounds and the caller has ensured that
367        // there is no mix of non-atomic and atomic operations.
368        unsafe { bindings::set_bit(index, self.as_ptr().cast_mut()) };
369    }
370
371    /// Clear `index` bit.
372    ///
373    /// ATTENTION: `clear_bit` is non-atomic, which differs from the naming
374    /// convention in C code. The corresponding C function is `__clear_bit`.
375    ///
376    /// If CONFIG_RUST_BITMAP_HARDENED is not enabled and `index` is greater than
377    /// or equal to `self.len()`, does nothing.
378    ///
379    /// # Panics
380    ///
381    /// Panics if CONFIG_RUST_BITMAP_HARDENED is enabled and `index` is greater than
382    /// or equal to `self.len()`.
383    #[inline]
384    pub fn clear_bit(&mut self, index: usize) {
385        bitmap_assert_return!(
386            index < self.len(),
387            "Bit `index` must be < {}, was {}",
388            self.len(),
389            index
390        );
391        // SAFETY: `index` is within bounds.
392        unsafe { bindings::__clear_bit(index, self.as_mut_ptr()) };
393    }
394
395    /// Clear `index` bit, atomically.
396    ///
397    /// This is a relaxed atomic operation (no implied memory barriers).
398    ///
399    /// ATTENTION: The naming convention differs from C, where the corresponding
400    /// function is called `clear_bit`.
401    ///
402    /// If CONFIG_RUST_BITMAP_HARDENED is not enabled and `index` is greater than
403    /// or equal to `self.len()`, does nothing.
404    ///
405    /// # Panics
406    ///
407    /// Panics if CONFIG_RUST_BITMAP_HARDENED is enabled and `index` is greater than
408    /// or equal to `self.len()`.
409    #[inline]
410    pub fn clear_bit_atomic(&self, index: usize) {
411        bitmap_assert_return!(
412            index < self.len(),
413            "Bit `index` must be < {}, was {}",
414            self.len(),
415            index
416        );
417        // SAFETY: `index` is within bounds and the caller has ensured that
418        // there is no mix of non-atomic and atomic operations.
419        unsafe { bindings::clear_bit(index, self.as_ptr().cast_mut()) };
420    }
421
422    /// Copy `src` into this [`Bitmap`] and set any remaining bits to zero.
423    ///
424    /// # Examples
425    ///
426    /// ```
427    /// use kernel::alloc::{AllocError, flags::GFP_KERNEL};
428    /// use kernel::bitmap::BitmapVec;
429    ///
430    /// let mut long_bitmap = BitmapVec::new(256, GFP_KERNEL)?;
431    ///
432    /// assert_eq!(None, long_bitmap.last_bit());
433    ///
434    /// let mut short_bitmap = BitmapVec::new(16, GFP_KERNEL)?;
435    ///
436    /// short_bitmap.set_bit(7);
437    /// long_bitmap.copy_and_extend(&short_bitmap);
438    /// assert_eq!(Some(7), long_bitmap.last_bit());
439    ///
440    /// # Ok::<(), AllocError>(())
441    /// ```
442    #[inline]
443    pub fn copy_and_extend(&mut self, src: &Bitmap) {
444        let len = core::cmp::min(src.len(), self.len());
445        // SAFETY: Access to `self` and `src` is within bounds. Both lengths fit in `u32`
446        // because a `Bitmap` is at most `i32::MAX` bits, so the casts are lossless.
447        unsafe {
448            bindings::bitmap_copy_and_extend(
449                self.as_mut_ptr(),
450                src.as_ptr(),
451                len as u32,
452                self.len() as u32,
453            )
454        };
455    }
456
457    /// Finds last set bit.
458    ///
459    /// # Examples
460    ///
461    /// ```
462    /// use kernel::alloc::{AllocError, flags::GFP_KERNEL};
463    /// use kernel::bitmap::BitmapVec;
464    ///
465    /// let bitmap = BitmapVec::new(64, GFP_KERNEL)?;
466    ///
467    /// match bitmap.last_bit() {
468    ///     Some(idx) => {
469    ///         pr_info!("The last bit has index {idx}.\n");
470    ///     }
471    ///     None => {
472    ///         pr_info!("All bits in this bitmap are 0.\n");
473    ///     }
474    /// }
475    /// # Ok::<(), AllocError>(())
476    /// ```
477    #[inline]
478    pub fn last_bit(&self) -> Option<usize> {
479        // SAFETY: `_find_next_bit` access is within bounds due to invariant.
480        let index = unsafe { bindings::_find_last_bit(self.as_ptr(), self.len()) };
481        if index >= self.len() {
482            None
483        } else {
484            Some(index)
485        }
486    }
487
488    /// Finds next set bit, starting from `start`.
489    ///
490    /// Returns `None` if `start` is greater or equal to `self.nbits`.
491    #[inline]
492    pub fn next_bit(&self, start: usize) -> Option<usize> {
493        bitmap_assert!(
494            start < self.len(),
495            "`start` must be < {} was {}",
496            self.len(),
497            start
498        );
499        // SAFETY: `_find_next_bit` tolerates out-of-bounds arguments and returns a
500        // value larger than or equal to `self.len()` in that case.
501        let index = unsafe { bindings::_find_next_bit(self.as_ptr(), self.len(), start) };
502        if index >= self.len() {
503            None
504        } else {
505            Some(index)
506        }
507    }
508
509    /// Finds next zero bit, starting from `start`.
510    /// Returns `None` if `start` is greater than or equal to `self.len()`.
511    #[inline]
512    pub fn next_zero_bit(&self, start: usize) -> Option<usize> {
513        bitmap_assert!(
514            start < self.len(),
515            "`start` must be < {} was {}",
516            self.len(),
517            start
518        );
519        // SAFETY: `_find_next_zero_bit` tolerates out-of-bounds arguments and returns a
520        // value larger than or equal to `self.len()` in that case.
521        let index = unsafe { bindings::_find_next_zero_bit(self.as_ptr(), self.len(), start) };
522        if index >= self.len() {
523            None
524        } else {
525            Some(index)
526        }
527    }
528}
529
530#[cfg(CONFIG_RUST_BITMAP_KUNIT_TEST)]
531#[macros::kunit_tests(rust_kernel_bitmap)]
532mod tests {
533    use super::*;
534    use kernel::alloc::flags::GFP_KERNEL;
535
536    #[test]
537    fn bitmap_borrow() {
538        let fake_bitmap: [usize; 2] = [0, 0];
539        let fake_bitmap_len = 2 * usize::BITS as usize;
540        // SAFETY: `fake_c_bitmap` is an array of expected length.
541        let b = unsafe { Bitmap::from_raw(fake_bitmap.as_ptr(), fake_bitmap_len) };
542        assert_eq!(fake_bitmap_len, b.len());
543        assert_eq!(None, b.next_bit(0));
544    }
545
546    #[test]
547    fn bitmap_copy() {
548        let fake_bitmap: usize = 0xFF;
549        // SAFETY: `fake_c_bitmap` can be used as one-element array of expected length.
550        let b = unsafe { Bitmap::from_raw(core::ptr::addr_of!(fake_bitmap), 8) };
551        assert_eq!(8, b.len());
552        assert_eq!(None, b.next_zero_bit(0));
553    }
554
555    #[test]
556    fn bitmap_vec_new() -> Result<(), AllocError> {
557        let b = BitmapVec::new(0, GFP_KERNEL)?;
558        assert_eq!(0, b.len());
559
560        let b = BitmapVec::new(3, GFP_KERNEL)?;
561        assert_eq!(3, b.len());
562
563        let b = BitmapVec::new(1024, GFP_KERNEL)?;
564        assert_eq!(1024, b.len());
565
566        // Requesting too large values results in [`AllocError`].
567        let res = BitmapVec::new(1 << 31, GFP_KERNEL);
568        assert!(res.is_err());
569        Ok(())
570    }
571
572    #[test]
573    fn bitmap_set_clear_find() -> Result<(), AllocError> {
574        let mut b = BitmapVec::new(128, GFP_KERNEL)?;
575
576        // Zero-initialized
577        assert_eq!(None, b.next_bit(0));
578        assert_eq!(Some(0), b.next_zero_bit(0));
579        assert_eq!(None, b.last_bit());
580
581        b.set_bit(17);
582
583        assert_eq!(Some(17), b.next_bit(0));
584        assert_eq!(Some(17), b.next_bit(17));
585        assert_eq!(None, b.next_bit(18));
586        assert_eq!(Some(17), b.last_bit());
587
588        b.set_bit(107);
589
590        assert_eq!(Some(17), b.next_bit(0));
591        assert_eq!(Some(17), b.next_bit(17));
592        assert_eq!(Some(107), b.next_bit(18));
593        assert_eq!(Some(107), b.last_bit());
594
595        b.clear_bit(17);
596
597        assert_eq!(Some(107), b.next_bit(0));
598        assert_eq!(Some(107), b.last_bit());
599        Ok(())
600    }
601
602    #[test]
603    fn owned_bitmap_out_of_bounds() -> Result<(), AllocError> {
604        // TODO: Kunit #[test]s do not support `cfg` yet,
605        // so we add it here in the body.
606        #[cfg(not(CONFIG_RUST_BITMAP_HARDENED))]
607        {
608            let mut b = BitmapVec::new(128, GFP_KERNEL)?;
609            b.set_bit(2048);
610            b.set_bit_atomic(2048);
611            b.clear_bit(2048);
612            b.clear_bit_atomic(2048);
613            assert_eq!(None, b.next_bit(2048));
614            assert_eq!(None, b.next_zero_bit(2048));
615            assert_eq!(None, b.last_bit());
616        }
617        Ok(())
618    }
619
620    // TODO: uncomment once kunit supports [should_panic] and `cfg`.
621    // #[cfg(CONFIG_RUST_BITMAP_HARDENED)]
622    // #[test]
623    // #[should_panic]
624    // fn owned_bitmap_out_of_bounds() -> Result<(), AllocError> {
625    //     let mut b = BitmapVec::new(128, GFP_KERNEL)?;
626    //
627    //     b.set_bit(2048);
628    // }
629
630    #[test]
631    fn bitmap_copy_and_extend() -> Result<(), AllocError> {
632        let mut long_bitmap = BitmapVec::new(256, GFP_KERNEL)?;
633
634        long_bitmap.set_bit(3);
635        long_bitmap.set_bit(200);
636
637        let mut short_bitmap = BitmapVec::new(32, GFP_KERNEL)?;
638
639        short_bitmap.set_bit(17);
640
641        long_bitmap.copy_and_extend(&short_bitmap);
642
643        // Previous bits have been cleared.
644        assert_eq!(Some(17), long_bitmap.next_bit(0));
645        assert_eq!(Some(17), long_bitmap.last_bit());
646        Ok(())
647    }
648}