WIP

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 22d9ea6..b7f4aa6 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -527,6 +527,16 @@ unsafe fn drop_rcu_ptr(ptr: *mut ffi::c_void) {
             unsafe { KBox::from_raw(ptr) }.drop_rcu();
         }
     }
+
+    type RcuBorrowed<'a> = &'a T;
+
+    unsafe fn rcu_borrow<'a>(ptr: *mut c_void) -> Self::RcuBorrowed<'a> {
+        // CAST: `ptr` should points the `ArcInner<T>` per implementation of `ForeignOwnable`.
+        let ptr = ptr.cast::<ArcInner<T>>();
+
+        // SAFETY: RCU guarantees the returned reference is valid for one grace period.
+        unsafe { &(*ptr).data }
+    }
 }
 
 impl<T: ?Sized> From<UniqueArc<T>> for Arc<T> {
diff --git a/rust/kernel/sync/rcu.rs b/rust/kernel/sync/rcu.rs
index 1210569..6083380 100644
--- a/rust/kernel/sync/rcu.rs
+++ b/rust/kernel/sync/rcu.rs
@@ -140,6 +140,16 @@ fn drop_rcu(self) {
         // SAFETY: `self.into_foreign()` is used immediately.
         unsafe { Self::drop_rcu_ptr(self.into_foreign()) };
     }
+
+    /// TODO
+    type RcuBorrowed<'a>;
+
+    /// TODO
+    ///
+    /// # Safety
+    ///
+    /// TODO
+    unsafe fn rcu_borrow<'a>(ptr: *mut c_void) -> Self::RcuBorrowed<'a>;
 }
 
 /// Drop and free the object in a rcu callback.
@@ -200,6 +210,13 @@ unsafe fn drop_rcu_ptr(ptr: *mut c_void) {
             }
         }
     }
+
+    type RcuBorrowed<'a> = &'a T;
+
+    unsafe fn rcu_borrow<'a>(ptr: *mut c_void) -> Self::RcuBorrowed<'a> {
+        // SAFETY: TODO
+        unsafe { <Self as ForeignOwnable>::borrow(ptr) }
+    }
 }
 
 /// A wrapper that uses the `drop_rcu()` instead of normal `drop()` of `T`.
@@ -247,12 +264,10 @@ pub fn new(t: T) -> Self {
     }
 
     /// Accesses the value while RCU read lock is held.
-    pub fn with_rcu<'rcu>(&self, _guard: &'rcu Guard) -> <T as ForeignOwnable>::Borrowed<'rcu> {
+    pub fn with_rcu<'rcu>(&self, _guard: &'rcu Guard) -> <T as DropRcu>::RcuBorrowed<'rcu> {
         // SAFETY: The function signature guarantees that the object outlives the returned
         // reference since the `RcuDrop::drop()` waits for a grace period.
-        //
-        // TODO: Use rcu_borrow?
-        unsafe { T::borrow(self.0) }
+        unsafe { T::rcu_borrow(self.0) }
     }
 }
 
@@ -285,3 +300,39 @@ unsafe fn borrow_mut<'a>(ptr: *mut c_void) -> Self::BorrowedMut<'a> {
         unsafe { T::borrow_mut(ptr) }
     }
 }
+
+/// `RcuDrop<T>` impl `Clone` if `T: Clone`.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::sync::{Arc, rcu::{DropRcu, RcuDrop, RcuHead, read_lock, WithRcuHead}};
+/// use core::ops::Deref;
+///
+/// let rcu_drop = RcuDrop::new(Arc::new(WithRcuHead::<i32>::new(42), GFP_KERNEL)?);
+/// let cloned = rcu_drop.clone();
+///
+/// let g = read_lock();
+/// let w = cloned.with_rcu(&g).deref();
+///
+/// drop(cloned);
+/// drop(rcu_drop); // <- kfree_rcu()
+///
+/// assert_eq!(*w, 42);
+///
+/// # Ok::<(), Error>(())
+/// ```
+impl<T: DropRcu + Clone> Clone for RcuDrop<T> {
+    fn clone(&self) -> Self {
+        let ptr = self.0;
+
+        // SAFETY: Normally it's unsafe but here we keep it in a `ManuallyDrop` as if the
+        // `from_foreign()` has not been called.
+        let temp = ManuallyDrop::new(unsafe { <T as ForeignOwnable>::from_foreign(ptr) });
+
+        let new = temp.deref().clone();
+
+        // INVARIANTS: Trivial.
+        Self(new.into_foreign(), PhantomData)
+    }
+}