Re: [PATCH v4 2/2] rust: zpool: add abstraction for zpool drivers

From: Vitaly Wool
Date: Thu Aug 28 2025 - 06:01:20 EST


<snip>
+    extern "C" fn destroy_(pool: *mut c_void) {
+        // SAFETY: The pointer originates from an `into_foreign` call.
+        T::destroy(unsafe { T::Pool::from_foreign(pool) })
+    }
+    extern "C" fn malloc_(
+        pool: *mut c_void,
+        size: usize,
+        gfp: u32,
+        handle: *mut usize,
+        nid: c_int,
+    ) -> c_int {
+        // SAFETY: The pointer originates from an `into_foreign` call. If `pool` is passed to
+        // `from_foreign`, then that happens in `_destroy` which will not be called during this
+        // method.
+        let pool = unsafe { T::Pool::borrow_mut(pool) };

Wait, can't this happen concurrently to all the other functions that borrow the
pool? This would be undefined behavior, no?

Theoretically, yes, but since pool is actually Box<T>, it's only the inner T that is mutable.

Anyway, the only reason for malloc() to require a mutable reference is that the backend implementation *may* use RBTree::cursor_lower_bound() which requires a mutable reference of the tree.

Would it be okay if I
* change the Zpool API so that malloc takes an immutable reference
* extend the RBTree API with a cursor_lower_bound analog which doesn't require a mutable tree?

As a matter of fact, the RBTree change may be postponed and submitted together with zblock, it is not relevant until then.

~Vitaly