From: Andreas Hindborg <a.hindborg@kernel.org>
To: "Tamir Duberstein" <tamird@gmail.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>
Cc: Daniel Gomez <da.gomez@kernel.org>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
Andreas Hindborg <a.hindborg@kernel.org>
Subject: [PATCH 10/10] rust: xarray: fix false positive lockdep warnings
Date: Wed, 03 Dec 2025 23:26:40 +0100 [thread overview]
Message-ID: <20251203-xarray-entry-send-v1-10-9e5ffd5e3cf0@kernel.org> (raw)
In-Reply-To: <20251203-xarray-entry-send-v1-0-9e5ffd5e3cf0@kernel.org>
Replace the `xa_init_flags` helper with direct initialization of XArray
structures using `__spin_lock_init`. This allows each XArray to have
its own lock class key for lockdep, preventing false positive warnings
about lock ordering violations.
Add a `new_xarray!` macro that automatically generates a unique lock
class key for each XArray instantiation site. The macro accepts an
optional name parameter and uses the `optional_name!` and
`static_lock_class!` macros to generate appropriate names and lock
classes.
Update the `XArray::new` method signature to accept explicit name and
lock class key parameters. This enables proper lockdep tracking while
maintaining flexibility for advanced use cases.
Remove `rust_helper_xa_init_flags` as it is now dead code.
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
rust/helpers/xarray.c | 5 ---
rust/kernel/xarray.rs | 74 +++++++++++++++++++++++++++++++++------------
rust/kernel/xarray/entry.rs | 55 ++++++++++++++++++---------------
3 files changed, 86 insertions(+), 48 deletions(-)
diff --git a/rust/helpers/xarray.c b/rust/helpers/xarray.c
index 425a6cc494734..2852f63388eea 100644
--- a/rust/helpers/xarray.c
+++ b/rust/helpers/xarray.c
@@ -7,11 +7,6 @@ int rust_helper_xa_err(void *entry)
return xa_err(entry);
}
-void rust_helper_xa_init_flags(struct xarray *xa, gfp_t flags)
-{
- return xa_init_flags(xa, flags);
-}
-
int rust_helper_xa_trylock(struct xarray *xa)
{
return xa_trylock(xa);
diff --git a/rust/kernel/xarray.rs b/rust/kernel/xarray.rs
index a405f2b6fdcad..c393d4c01af2a 100644
--- a/rust/kernel/xarray.rs
+++ b/rust/kernel/xarray.rs
@@ -29,6 +29,8 @@
Result, //
},
ffi::c_void,
+ str::CStr,
+ sync::LockClassKey,
types::{
ForeignOwnable,
NotThreadSafe,
@@ -48,6 +50,19 @@
mod preload;
+/// Creates a [`XArray`] initialiser with the given name and a newly-created lock class.
+///
+/// It uses the name if one is given, otherwise it generates one based on the file name and line
+/// number.
+#[macro_export]
+macro_rules! new_xarray {
+ ($kind:expr $(, $name:literal)? $(,)?) => {
+ $crate::xarray::XArray::new(
+ $kind, $crate::optional_name!($($name)?), $crate::static_lock_class!())
+ };
+}
+pub use new_xarray;
+
/// An array which efficiently maps sparse integer indices to owned objects.
///
/// This is similar to a [`crate::alloc::kvec::Vec<Option<T>>`], but more efficient when there are
@@ -62,9 +77,10 @@
///
/// ```rust
/// use kernel::alloc::KBox;
-/// use kernel::xarray::{AllocKind, XArray};
+/// use kernel::xarray::{new_xarray, AllocKind, XArray};
///
-/// let xa = KBox::pin_init(XArray::new(AllocKind::Alloc1), GFP_KERNEL)?;
+/// let xa: Pin<KBox<XArray<KBox<u32>>>> =
+/// KBox::pin_init(new_xarray!(AllocKind::Alloc1), GFP_KERNEL)?;
///
/// let dead = KBox::new(0xdead, GFP_KERNEL)?;
/// let beef = KBox::new(0xbeef, GFP_KERNEL)?;
@@ -124,7 +140,11 @@ pub enum AllocKind {
impl<T: ForeignOwnable> XArray<T> {
/// Creates a new initializer for this type.
- pub fn new(kind: AllocKind) -> impl PinInit<Self> {
+ pub fn new(
+ kind: AllocKind,
+ name: &'static CStr,
+ key: Pin<&'static LockClassKey>,
+ ) -> impl PinInit<Self> {
let flags = match kind {
AllocKind::Alloc => bindings::XA_FLAGS_ALLOC,
AllocKind::Alloc1 => bindings::XA_FLAGS_ALLOC1,
@@ -133,8 +153,14 @@ pub fn new(kind: AllocKind) -> impl PinInit<Self> {
// SAFETY: `xa` is valid while the closure is called.
//
// INVARIANT: `xa` is initialized here to an empty, valid [`bindings::xarray`].
- xa <- Opaque::ffi_init(|xa| unsafe {
- bindings::xa_init_flags(xa, flags)
+ xa <- Opaque::ffi_init(|xa: *mut bindings::xarray| unsafe {
+ bindings::__spin_lock_init(
+ &raw mut (*xa).xa_lock,
+ name.as_ptr().cast(),
+ key.as_ptr(),
+ );
+ (*xa).xa_flags = flags;
+ (*xa).xa_head = null_mut();
}),
_p: PhantomData,
})
@@ -236,8 +262,12 @@ fn load(&self, index: usize) -> Option<NonNull<c_void>> {
/// # Examples
///
/// ```
- /// # use kernel::{alloc::{flags::GFP_KERNEL, kbox::KBox}, xarray::{AllocKind, XArray}};
- /// let xa = KBox::pin_init(XArray::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{
+ /// # alloc::{flags::GFP_KERNEL, kbox::KBox},
+ /// # xarray::{new_xarray, AllocKind, XArray},
+ /// # };
+ /// let xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
///
/// let mut guard = xa.lock();
/// assert_eq!(guard.contains_index(42), false);
@@ -272,8 +302,9 @@ pub fn get_mut(&mut self, index: usize) -> Option<T::BorrowedMut<'_>> {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// assert_eq!(guard.contains_index(42), false);
@@ -309,8 +340,9 @@ fn load_next(&self, index: usize) -> Option<(usize, NonNull<c_void>)> {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(10, KBox::new(10u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -339,8 +371,9 @@ pub fn find_next(&self, index: usize) -> Option<(usize, T::Borrowed<'_>)> {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(10, KBox::new(10u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -366,8 +399,9 @@ pub fn find_next_mut(&mut self, index: usize) -> Option<(usize, T::BorrowedMut<'
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(10, KBox::new(10u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -401,8 +435,9 @@ pub fn find_next_entry<'b>(&'b mut self, index: usize) -> Option<OccupiedEntry<'
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(100, KBox::new(42u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -505,8 +540,9 @@ pub fn store(
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// assert_eq!(guard.get(42), None);
diff --git a/rust/kernel/xarray/entry.rs b/rust/kernel/xarray/entry.rs
index 2d6ef4781f47d..6e370252309fc 100644
--- a/rust/kernel/xarray/entry.rs
+++ b/rust/kernel/xarray/entry.rs
@@ -26,8 +26,9 @@ impl<T: ForeignOwnable> Entry<'_, '_, T> {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// let entry = guard.get_entry(42);
@@ -100,17 +101,17 @@ fn insert_internal(
///
/// Returns a reference to the newly inserted value.
///
- /// - This method will fail if the nodes on the path to the index
- /// represented by this entry are not present in the XArray and no memory
- /// is available via the `preload` argument.
+ /// - This method will fail if the nodes on the path to the index represented by this entry are
+ /// not present in the XArray and no memory is available via the `preload` argument.
/// - This method will not drop the XArray lock.
///
///
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// assert_eq!(guard.get(42), None);
@@ -139,16 +140,16 @@ pub fn insert(
/// Inserts a value and returns an occupied entry representing the newly inserted value.
///
- /// - This method will fail if the nodes on the path to the index
- /// represented by this entry are not present in the XArray and no memory
- /// is available via the `preload` argument.
+ /// - This method will fail if the nodes on the path to the index represented by this entry are
+ /// not present in the XArray and no memory is available via the `preload` argument.
/// - This method will not drop the XArray lock.
///
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// assert_eq!(guard.get(42), None);
@@ -182,8 +183,9 @@ pub fn insert_entry(
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// assert_eq!(guard.get(42), None);
@@ -221,8 +223,9 @@ pub(crate) fn new(guard: &'b mut Guard<'a, T>, index: usize, ptr: NonNull<c_void
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(42, KBox::new(0x1337u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -266,8 +269,9 @@ pub fn remove(mut self) -> T {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(42, KBox::new(0x1337u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -287,8 +291,9 @@ pub fn index(&self) -> usize {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(42, KBox::new(0x1337u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -334,8 +339,9 @@ pub fn insert(&mut self, value: T) -> T {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(42, KBox::new(0x1337u32, GFP_KERNEL)?, GFP_KERNEL)?;
@@ -361,8 +367,9 @@ pub fn into_mut(self) -> T::BorrowedMut<'b> {
/// # Examples
///
/// ```
- /// # use kernel::{prelude::*, xarray::{AllocKind, XArray, Entry}};
- /// let mut xa = KBox::pin_init(XArray::<KBox<u32>>::new(AllocKind::Alloc), GFP_KERNEL)?;
+ /// # use kernel::{prelude::*, xarray::{new_xarray, AllocKind, XArray, Entry}};
+ /// let mut xa: Pin<KBox<XArray<KBox<u32>>>> =
+ /// KBox::pin_init(new_xarray!(AllocKind::Alloc), GFP_KERNEL)?;
/// let mut guard = xa.lock();
///
/// guard.store(42, KBox::new(100u32, GFP_KERNEL)?, GFP_KERNEL)?;
--
2.51.2
next prev parent reply other threads:[~2025-12-03 22:28 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-03 22:26 [PATCH 00/10] rust: xarray: add entry API with preloading Andreas Hindborg
2025-12-03 22:26 ` [PATCH 01/10] rust: xarray: minor formatting fixes Andreas Hindborg
2025-12-29 15:56 ` Tamir Duberstein
2025-12-29 15:58 ` Tamir Duberstein
2026-01-21 15:45 ` Gary Guo
2025-12-03 22:26 ` [PATCH 02/10] rust: xarray: add debug format for `StoreError` Andreas Hindborg
2025-12-29 15:58 ` Tamir Duberstein
2026-01-21 15:46 ` Gary Guo
2025-12-03 22:26 ` [PATCH 03/10] rust: xarray: add `contains_index` method Andreas Hindborg
2025-12-29 15:59 ` Tamir Duberstein
2026-01-07 18:34 ` Andreas Hindborg
2026-01-07 18:38 ` Tamir Duberstein
2026-01-08 9:29 ` Andreas Hindborg
2026-01-08 11:05 ` Tamir Duberstein
2026-01-09 10:38 ` Andreas Hindborg
2026-01-09 15:59 ` Tamir Duberstein
2026-01-09 17:04 ` Gary Guo
2025-12-03 22:26 ` [PATCH 04/10] rust: xarray: add `XArrayState` Andreas Hindborg
2025-12-29 16:04 ` Tamir Duberstein
2026-01-07 18:48 ` Andreas Hindborg
2026-01-08 14:22 ` Gary Guo
2025-12-03 22:26 ` [PATCH 05/10] rust: xarray: use `xas_load` instead of `xa_load` in `Guard::load` Andreas Hindborg
2025-12-29 16:06 ` Tamir Duberstein
2026-01-07 19:19 ` Andreas Hindborg
2026-01-07 20:06 ` Tamir Duberstein
2026-01-08 9:30 ` Andreas Hindborg
2025-12-03 22:26 ` [PATCH 06/10] rust: xarray: simplify `Guard::load` Andreas Hindborg
2025-12-29 16:07 ` Tamir Duberstein
2026-01-07 19:25 ` Andreas Hindborg
2026-01-07 20:08 ` Tamir Duberstein
2026-01-08 9:38 ` Andreas Hindborg
2026-01-08 11:07 ` Tamir Duberstein
2026-01-09 16:57 ` Gary Guo
2025-12-03 22:26 ` [PATCH 07/10] rust: xarray: add `find_next` and `find_next_mut` Andreas Hindborg
2025-12-29 16:11 ` Tamir Duberstein
2026-01-07 19:29 ` Andreas Hindborg
2025-12-03 22:26 ` [PATCH 08/10] rust: xarray: add entry API Andreas Hindborg
2025-12-29 16:25 ` Tamir Duberstein
2026-01-08 9:25 ` Andreas Hindborg
2026-01-08 11:03 ` Tamir Duberstein
2026-01-09 10:36 ` Andreas Hindborg
2026-01-09 16:00 ` Tamir Duberstein
2025-12-03 22:26 ` [PATCH 09/10] rust: xarray: add preload API Andreas Hindborg
2026-01-21 15:56 ` Gary Guo
2026-01-21 19:09 ` Andreas Hindborg
2025-12-03 22:26 ` Andreas Hindborg [this message]
2025-12-29 16:29 ` [PATCH 10/10] rust: xarray: fix false positive lockdep warnings Tamir Duberstein
2026-02-06 14:22 ` Andreas Hindborg
2026-01-21 15:59 ` Gary Guo
2026-01-21 19:01 ` Andreas Hindborg
2026-01-21 19:10 ` Gary Guo
2026-01-21 20:17 ` Andreas Hindborg
2026-01-22 9:20 ` Alice Ryhl
2026-02-06 14:21 ` Andreas Hindborg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251203-xarray-entry-send-v1-10-9e5ffd5e3cf0@kernel.org \
--to=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=da.gomez@kernel.org \
--cc=dakr@kernel.org \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@gmail.com \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.