From 84da4b22b8b21900305e4f19cca9927cb8a35666 Mon Sep 17 00:00:00 2001
From: Ayaan Zaidi <zaidi.ayaan@gmail.com>
Date: Sun, 23 May 2021 15:46:25 +0530
Subject: [PATCH] rust: make SharedState::try_new() return a pinned Arc

Pinning the Arc immediately guarantees no way to obtain a
Arc<SharedState>, but only a Pin<Arc<SharedState>>

Signed-off-by: Ayaan Zaidi <zaidi.ayaan@gmail.com>
---
 samples/rust/rust_miscdev.rs | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/samples/rust/rust_miscdev.rs b/samples/rust/rust_miscdev.rs
index 12171172378f72..a3c65fb3077012 100644
--- a/samples/rust/rust_miscdev.rs
+++ b/samples/rust/rust_miscdev.rs
@@ -38,13 +38,16 @@ struct SharedState {
 }
 
 impl SharedState {
-    fn try_new() -> Result<Arc<Self>> {
-        let state = Arc::try_new(Self {
-            // SAFETY: `condvar_init!` is called below.
-            state_changed: unsafe { CondVar::new() },
-            // SAFETY: `mutex_init!` is called below.
-            inner: unsafe { Mutex::new(SharedStateInner { token_count: 0 }) },
-        })?;
+    fn try_new() -> Result<Pin<Arc<Self>>> {
+        // SAFETY: `state` is pinning `Arc`, which implements `Unpin`.
+        let state = unsafe {
+            Pin::new_unchecked(Arc::try_new(Self {
+                // SAFETY: `condvar_init!` is called below.
+                state_changed: CondVar::new(),
+                // SAFETY: `mutex_init!` is called below.
+                inner: Mutex::new(SharedStateInner { token_count: 0 }),
+            })?)
+        };
         // SAFETY: `state_changed` is pinned behind `Arc`.
         let state_changed = unsafe { Pin::new_unchecked(&state.state_changed) };
         kernel::condvar_init!(state_changed, "SharedState::state_changed");
@@ -56,11 +59,11 @@ impl SharedState {
 }
 
 struct Token {
-    shared: Arc<SharedState>,
+    shared: Pin<Arc<SharedState>>,
 }
 
-impl FileOpener<Arc<SharedState>> for Token {
-    fn open(shared: &Arc<SharedState>) -> Result<Self::Wrapper> {
+impl FileOpener<Pin<Arc<SharedState>>> for Token {
+    fn open(shared: &Pin<Arc<SharedState>>) -> Result<Self::Wrapper> {
         Ok(Box::try_new(Self {
             shared: shared.clone(),
         })?)
@@ -122,7 +125,7 @@ impl FileOperations for Token {
 }
 
 struct RustMiscdev {
-    _dev: Pin<Box<miscdev::Registration<Arc<SharedState>>>>,
+    _dev: Pin<Box<miscdev::Registration<Pin<Arc<SharedState>>>>>,
 }
 
 impl KernelModule for RustMiscdev {