gpt_component/
partitions_directory.rs1use crate::gpt::GptManager;
6use block_server::{BlockServer, SessionManager};
7use fuchsia_sync::Mutex;
8use std::collections::BTreeMap;
9use std::sync::{Arc, Weak};
10use vfs::directory::helper::DirectlyMutable as _;
11
12pub struct PartitionsDirectory {
14 node: Arc<vfs::directory::immutable::Simple>,
15 entries: Mutex<BTreeMap<String, PartitionsDirectoryEntry>>,
16}
17
18impl std::fmt::Debug for PartitionsDirectory {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
20 f.debug_struct("PartitionDirectory").field("entries", &self.entries).finish()
21 }
22}
23
24impl PartitionsDirectory {
25 pub fn new(node: Arc<vfs::directory::immutable::Simple>) -> Self {
26 Self { node, entries: Default::default() }
27 }
28
29 pub fn clear(&self) {
30 self.node.remove_all_entries();
31 self.entries.lock().clear();
32 }
33
34 pub fn add_partition<SM: SessionManager + Send + Sync + 'static>(
36 &self,
37 name: &str,
38 block_server: Weak<BlockServer<SM>>,
39 gpt_manager: Weak<GptManager>,
40 gpt_index: usize,
41 ) {
42 let entry = PartitionsDirectoryEntry::new_partition(block_server, gpt_manager, gpt_index);
43 self.node.add_entry(name, entry.node.clone()).expect("Added an entry twice");
44 self.entries.lock().insert(name.to_string(), entry);
45 }
46
47 pub fn add_overlay<SM: SessionManager + Send + Sync + 'static>(
49 &self,
50 name: &str,
51 block_server: Weak<BlockServer<SM>>,
52 gpt_manager: Weak<GptManager>,
53 gpt_indexes: Vec<usize>,
54 ) {
55 let entry = PartitionsDirectoryEntry::new_overlay(block_server, gpt_manager, gpt_indexes);
56 self.node.add_entry(name, entry.node.clone()).expect("Added an entry twice");
57 self.entries.lock().insert(name.to_string(), entry);
58 }
59}
60
61pub struct PartitionsDirectoryEntry {
63 node: Arc<vfs::directory::immutable::Simple>,
64}
65
66impl std::fmt::Debug for PartitionsDirectoryEntry {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
68 f.debug_struct("PartitionDirectoryEntry").finish()
69 }
70}
71
72impl PartitionsDirectoryEntry {
73 fn new_partition<SM: SessionManager + Send + Sync + 'static>(
74 block_server: Weak<BlockServer<SM>>,
75 gpt_manager: Weak<GptManager>,
76 gpt_index: usize,
77 ) -> Self {
78 let node = vfs::directory::immutable::simple();
79 node.add_entry(
80 "volume",
81 vfs::service::host(move |requests| {
82 let server = block_server.clone();
83 async move {
84 if let Some(server) = server.upgrade() {
85 if let Err(err) = server.handle_requests(requests).await {
86 log::error!(err:?; "Error handling requests");
87 }
88 }
89 }
90 }),
91 )
92 .unwrap();
93 node.add_entry(
94 "partition",
95 vfs::service::host(move |requests| {
96 let manager = gpt_manager.clone();
97 async move {
98 if let Some(manager) = manager.upgrade() {
99 if let Err(err) =
100 manager.handle_partitions_requests(gpt_index, requests).await
101 {
102 log::error!(err:?; "Error handling requests");
103 }
104 }
105 }
106 }),
107 )
108 .unwrap();
109
110 Self { node }
111 }
112
113 fn new_overlay<SM: SessionManager + Send + Sync + 'static>(
114 block_server: Weak<BlockServer<SM>>,
115 gpt_manager: Weak<GptManager>,
116 gpt_indexes: Vec<usize>,
117 ) -> Self {
118 let node = vfs::directory::immutable::simple();
119 node.add_entry(
120 "volume",
121 vfs::service::host(move |requests| {
122 let server = block_server.clone();
123 async move {
124 if let Some(server) = server.upgrade() {
125 if let Err(err) = server.handle_requests(requests).await {
126 log::error!(err:?; "Error handling requests");
127 }
128 }
129 }
130 }),
131 )
132 .unwrap();
133 node.add_entry(
134 "overlay",
135 vfs::service::host(move |requests| {
136 let manager = gpt_manager.clone();
137 let gpt_indexes = gpt_indexes.clone();
138 async move {
139 if let Some(manager) = manager.upgrade() {
140 if let Err(err) =
141 manager.handle_overlay_partitions_requests(gpt_indexes, requests).await
142 {
143 log::error!(err:?; "Error handling requests");
144 }
145 }
146 }
147 }),
148 )
149 .unwrap();
150
151 Self { node }
152 }
153}