1#![allow(dead_code)]
11
12use alloc::boxed::Box;
13use alloc::collections::BTreeMap;
14use alloc::string::String;
15use alloc::sync::Arc;
16use alloc::vec::Vec;
17use core::mem::MaybeUninit;
18
19use async_lock::{Mutex, RwLock};
20use async_trait::async_trait;
21
22use crate::executor::block_on;
23use crate::fd::{AccessPermission, ObjectInterface, OpenOption, PollEvent};
24use crate::fs::{DirectoryEntry, FileAttr, NodeKind, SeekWhence, VfsNode};
25use crate::time::timespec;
26use crate::{arch, io};
27
28#[derive(Debug)]
29pub(crate) struct RomFileInner {
30 pub data: &'static [u8],
31 pub attr: FileAttr,
32}
33
34impl RomFileInner {
35 pub fn new(data: &'static [u8], attr: FileAttr) -> Self {
36 Self { data, attr }
37 }
38}
39
40#[derive(Debug, Clone)]
41struct RomFileInterface {
42 pos: Arc<Mutex<usize>>,
44 inner: Arc<RwLock<RomFileInner>>,
46}
47
48#[async_trait]
49impl ObjectInterface for RomFileInterface {
50 async fn poll(&self, event: PollEvent) -> io::Result<PollEvent> {
51 let len = self.inner.read().await.data.len();
52 let pos = *self.pos.lock().await;
53
54 let ret = if pos < len {
55 event.intersection(PollEvent::POLLIN | PollEvent::POLLRDNORM | PollEvent::POLLRDBAND)
56 } else {
57 PollEvent::empty()
58 };
59
60 Ok(ret)
61 }
62
63 async fn read(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
64 {
65 let microseconds = arch::kernel::systemtime::now_micros();
66 let t = timespec::from_usec(microseconds as i64);
67 let mut guard = self.inner.write().await;
68 guard.attr.st_atim = t;
69 }
70
71 let vec = self.inner.read().await.data;
72 let mut pos_guard = self.pos.lock().await;
73 let pos = *pos_guard;
74
75 if pos >= vec.len() {
76 return Ok(0);
77 }
78
79 let len = if vec.len() - pos < buf.len() {
80 vec.len() - pos
81 } else {
82 buf.len()
83 };
84
85 buf[..len].write_copy_of_slice(&vec[pos..pos + len]);
86 *pos_guard = pos + len;
87
88 Ok(len)
89 }
90
91 async fn lseek(&self, offset: isize, whence: SeekWhence) -> io::Result<isize> {
92 let guard = self.inner.read().await;
93 let mut pos_guard = self.pos.lock().await;
94
95 let new_pos: isize = if whence == SeekWhence::Set {
96 if offset < 0 {
97 return Err(io::Error::EINVAL);
98 }
99
100 offset
101 } else if whence == SeekWhence::End {
102 guard.data.len() as isize + offset
103 } else if whence == SeekWhence::Cur {
104 (*pos_guard as isize) + offset
105 } else {
106 return Err(io::Error::EINVAL);
107 };
108
109 if new_pos <= isize::try_from(guard.data.len()).unwrap() {
110 *pos_guard = new_pos.try_into().unwrap();
111 Ok(new_pos)
112 } else {
113 Err(io::Error::EBADF)
114 }
115 }
116
117 async fn fstat(&self) -> io::Result<FileAttr> {
118 let guard = self.inner.read().await;
119 Ok(guard.attr)
120 }
121}
122
123impl RomFileInterface {
124 pub fn new(inner: Arc<RwLock<RomFileInner>>) -> Self {
125 Self {
126 pos: Arc::new(Mutex::new(0)),
127 inner,
128 }
129 }
130
131 pub fn len(&self) -> usize {
132 block_on(async { Ok(self.inner.read().await.data.len()) }, None).unwrap()
133 }
134}
135
136#[derive(Debug)]
137pub(crate) struct RamFileInner {
138 pub data: Vec<u8>,
139 pub attr: FileAttr,
140}
141
142impl RamFileInner {
143 pub fn new(attr: FileAttr) -> Self {
144 Self {
145 data: Vec::new(),
146 attr,
147 }
148 }
149}
150
151#[derive(Debug, Clone)]
152pub struct RamFileInterface {
153 pos: Arc<Mutex<usize>>,
155 inner: Arc<RwLock<RamFileInner>>,
157}
158
159#[async_trait]
160impl ObjectInterface for RamFileInterface {
161 async fn poll(&self, event: PollEvent) -> io::Result<PollEvent> {
162 let len = self.inner.read().await.data.len();
163 let pos = *self.pos.lock().await;
164
165 let mut available = PollEvent::POLLOUT | PollEvent::POLLWRNORM | PollEvent::POLLWRBAND;
166
167 if pos < len {
168 available.insert(PollEvent::POLLIN | PollEvent::POLLRDNORM | PollEvent::POLLRDBAND);
169 }
170
171 Ok(event & available)
172 }
173
174 async fn read(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> {
175 {
176 let microseconds = arch::kernel::systemtime::now_micros();
177 let t = timespec::from_usec(microseconds as i64);
178 let mut guard = self.inner.write().await;
179 guard.attr.st_atim = t;
180 }
181
182 let guard = self.inner.read().await;
183 let mut pos_guard = self.pos.lock().await;
184 let pos = *pos_guard;
185
186 if pos >= guard.data.len() {
187 return Ok(0);
188 }
189
190 let len = if guard.data.len() - pos < buf.len() {
191 guard.data.len() - pos
192 } else {
193 buf.len()
194 };
195
196 buf[..len].write_copy_of_slice(&guard.data[pos..pos + len]);
197 *pos_guard = pos + len;
198
199 Ok(len)
200 }
201
202 async fn write(&self, buf: &[u8]) -> io::Result<usize> {
203 let microseconds = arch::kernel::systemtime::now_micros();
204 let t = timespec::from_usec(microseconds as i64);
205 let mut guard = self.inner.write().await;
206 let mut pos_guard = self.pos.lock().await;
207 let pos = *pos_guard;
208
209 if pos + buf.len() > guard.data.len() {
210 guard.data.resize(pos + buf.len(), 0);
211 guard.attr.st_size = guard.data.len().try_into().unwrap();
212 }
213
214 guard.attr.st_atim = t;
215 guard.attr.st_mtim = t;
216 guard.attr.st_ctim = t;
217
218 guard.data[pos..pos + buf.len()].copy_from_slice(buf);
219 *pos_guard = pos + buf.len();
220
221 Ok(buf.len())
222 }
223
224 async fn lseek(&self, offset: isize, whence: SeekWhence) -> io::Result<isize> {
225 let mut guard = self.inner.write().await;
226 let mut pos_guard = self.pos.lock().await;
227
228 let new_pos: isize = if whence == SeekWhence::Set {
229 if offset < 0 {
230 return Err(io::Error::EINVAL);
231 }
232
233 offset
234 } else if whence == SeekWhence::End {
235 guard.data.len() as isize + offset
236 } else if whence == SeekWhence::Cur {
237 (*pos_guard as isize) + offset
238 } else {
239 return Err(io::Error::EINVAL);
240 };
241
242 if new_pos > isize::try_from(guard.data.len()).unwrap() {
243 guard.data.resize(new_pos.try_into().unwrap(), 0);
244 guard.attr.st_size = guard.data.len().try_into().unwrap();
245 }
246 *pos_guard = new_pos.try_into().unwrap();
247
248 Ok(new_pos)
249 }
250
251 async fn fstat(&self) -> io::Result<FileAttr> {
252 let guard = self.inner.read().await;
253 Ok(guard.attr)
254 }
255}
256
257impl RamFileInterface {
258 pub fn new(inner: Arc<RwLock<RamFileInner>>) -> Self {
259 Self {
260 pos: Arc::new(Mutex::new(0)),
261 inner,
262 }
263 }
264
265 pub fn len(&self) -> usize {
266 block_on(async { Ok(self.inner.read().await.data.len()) }, None).unwrap()
267 }
268}
269
270#[derive(Debug)]
271pub(crate) struct RomFile {
272 data: Arc<RwLock<RomFileInner>>,
273}
274
275impl VfsNode for RomFile {
276 fn get_kind(&self) -> NodeKind {
277 NodeKind::File
278 }
279
280 fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
281 Ok(Arc::new(RomFileInterface::new(self.data.clone())))
282 }
283
284 fn get_file_attributes(&self) -> io::Result<FileAttr> {
285 block_on(async { Ok(self.data.read().await.attr) }, None)
286 }
287
288 fn traverse_lstat(&self, components: &mut Vec<&str>) -> io::Result<FileAttr> {
289 if components.is_empty() {
290 self.get_file_attributes()
291 } else {
292 Err(io::Error::EBADF)
293 }
294 }
295
296 fn traverse_stat(&self, components: &mut Vec<&str>) -> io::Result<FileAttr> {
297 if components.is_empty() {
298 self.get_file_attributes()
299 } else {
300 Err(io::Error::EBADF)
301 }
302 }
303}
304
305impl RomFile {
306 pub fn new(data: &'static [u8], mode: AccessPermission) -> Self {
307 let microseconds = arch::kernel::systemtime::now_micros();
308 let t = timespec::from_usec(microseconds as i64);
309 let attr = FileAttr {
310 st_size: data.len().try_into().unwrap(),
311 st_mode: mode | AccessPermission::S_IFREG,
312 st_atim: t,
313 st_mtim: t,
314 st_ctim: t,
315 ..Default::default()
316 };
317
318 Self {
319 data: Arc::new(RwLock::new(RomFileInner::new(data, attr))),
320 }
321 }
322}
323
324#[derive(Debug, Clone)]
325pub(crate) struct RamFile {
326 data: Arc<RwLock<RamFileInner>>,
327}
328
329impl VfsNode for RamFile {
330 fn get_kind(&self) -> NodeKind {
331 NodeKind::File
332 }
333
334 fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
335 Ok(Arc::new(RamFileInterface::new(self.data.clone())))
336 }
337
338 fn get_file_attributes(&self) -> io::Result<FileAttr> {
339 block_on(async { Ok(self.data.read().await.attr) }, None)
340 }
341
342 fn traverse_lstat(&self, components: &mut Vec<&str>) -> io::Result<FileAttr> {
343 if components.is_empty() {
344 self.get_file_attributes()
345 } else {
346 Err(io::Error::EBADF)
347 }
348 }
349
350 fn traverse_stat(&self, components: &mut Vec<&str>) -> io::Result<FileAttr> {
351 if components.is_empty() {
352 self.get_file_attributes()
353 } else {
354 Err(io::Error::EBADF)
355 }
356 }
357}
358
359impl RamFile {
360 pub fn new(mode: AccessPermission) -> Self {
361 let microseconds = arch::kernel::systemtime::now_micros();
362 let t = timespec::from_usec(microseconds as i64);
363 let attr = FileAttr {
364 st_mode: mode | AccessPermission::S_IFREG,
365 st_atim: t,
366 st_mtim: t,
367 st_ctim: t,
368 ..Default::default()
369 };
370
371 Self {
372 data: Arc::new(RwLock::new(RamFileInner::new(attr))),
373 }
374 }
375}
376
377#[derive(Debug, Clone)]
378pub struct MemDirectoryInterface {
379 inner:
381 Arc<RwLock<BTreeMap<String, Box<dyn VfsNode + core::marker::Send + core::marker::Sync>>>>,
382}
383
384impl MemDirectoryInterface {
385 pub fn new(
386 inner: Arc<
387 RwLock<BTreeMap<String, Box<dyn VfsNode + core::marker::Send + core::marker::Sync>>>,
388 >,
389 ) -> Self {
390 Self { inner }
391 }
392}
393
394#[async_trait]
395impl ObjectInterface for MemDirectoryInterface {
396 async fn readdir(&self) -> io::Result<Vec<DirectoryEntry>> {
397 let mut entries: Vec<DirectoryEntry> = Vec::new();
398 for name in self.inner.read().await.keys() {
399 entries.push(DirectoryEntry::new(name.clone()));
400 }
401
402 Ok(entries)
403 }
404}
405
406#[derive(Debug)]
407pub(crate) struct MemDirectory {
408 inner:
409 Arc<RwLock<BTreeMap<String, Box<dyn VfsNode + core::marker::Send + core::marker::Sync>>>>,
410 attr: FileAttr,
411}
412
413impl MemDirectory {
414 pub fn new(mode: AccessPermission) -> Self {
415 let microseconds = arch::kernel::systemtime::now_micros();
416 let t = timespec::from_usec(microseconds as i64);
417
418 Self {
419 inner: Arc::new(RwLock::new(BTreeMap::new())),
420 attr: FileAttr {
421 st_mode: mode | AccessPermission::S_IFDIR,
422 st_atim: t,
423 st_mtim: t,
424 st_ctim: t,
425 ..Default::default()
426 },
427 }
428 }
429
430 async fn async_traverse_open(
431 &self,
432 components: &mut Vec<&str>,
433 opt: OpenOption,
434 mode: AccessPermission,
435 ) -> io::Result<Arc<dyn ObjectInterface>> {
436 if let Some(component) = components.pop() {
437 let node_name = String::from(component);
438
439 if components.is_empty() {
440 let mut guard = self.inner.write().await;
441 if let Some(file) = guard.get(&node_name) {
442 if opt.contains(OpenOption::O_DIRECTORY)
443 && file.get_kind() != NodeKind::Directory
444 {
445 return Err(io::Error::ENOTDIR);
446 }
447
448 if file.get_kind() == NodeKind::File || file.get_kind() == NodeKind::Directory {
449 return file.get_object();
450 } else {
451 return Err(io::Error::ENOENT);
452 }
453 } else if opt.contains(OpenOption::O_CREAT) {
454 let file = Box::new(RamFile::new(mode));
455 guard.insert(node_name, file.clone());
456 return Ok(Arc::new(RamFileInterface::new(file.data.clone())));
457 } else {
458 return Err(io::Error::ENOENT);
459 }
460 }
461
462 if let Some(directory) = self.inner.read().await.get(&node_name) {
463 return directory.traverse_open(components, opt, mode);
464 }
465 }
466
467 Err(io::Error::ENOENT)
468 }
469}
470
471impl VfsNode for MemDirectory {
472 fn get_kind(&self) -> NodeKind {
473 NodeKind::Directory
474 }
475
476 fn get_object(&self) -> io::Result<Arc<dyn ObjectInterface>> {
477 Ok(Arc::new(MemDirectoryInterface::new(self.inner.clone())))
478 }
479
480 fn get_file_attributes(&self) -> io::Result<FileAttr> {
481 Ok(self.attr)
482 }
483
484 fn traverse_mkdir(&self, components: &mut Vec<&str>, mode: AccessPermission) -> io::Result<()> {
485 block_on(
486 async {
487 if let Some(component) = components.pop() {
488 let node_name = String::from(component);
489
490 if let Some(directory) = self.inner.read().await.get(&node_name) {
491 return directory.traverse_mkdir(components, mode);
492 }
493
494 if components.is_empty() {
495 self.inner
496 .write()
497 .await
498 .insert(node_name, Box::new(MemDirectory::new(mode)));
499 return Ok(());
500 }
501 }
502
503 Err(io::Error::EBADF)
504 },
505 None,
506 )
507 }
508
509 fn traverse_rmdir(&self, components: &mut Vec<&str>) -> io::Result<()> {
510 block_on(
511 async {
512 if let Some(component) = components.pop() {
513 let node_name = String::from(component);
514
515 if components.is_empty() {
516 let mut guard = self.inner.write().await;
517
518 let obj = guard.remove(&node_name).ok_or(io::Error::ENOENT)?;
519 if obj.get_kind() == NodeKind::Directory {
520 return Ok(());
521 } else {
522 guard.insert(node_name, obj);
523 return Err(io::Error::ENOTDIR);
524 }
525 } else if let Some(directory) = self.inner.read().await.get(&node_name) {
526 return directory.traverse_rmdir(components);
527 }
528 }
529
530 Err(io::Error::EBADF)
531 },
532 None,
533 )
534 }
535
536 fn traverse_unlink(&self, components: &mut Vec<&str>) -> io::Result<()> {
537 block_on(
538 async {
539 if let Some(component) = components.pop() {
540 let node_name = String::from(component);
541
542 if components.is_empty() {
543 let mut guard = self.inner.write().await;
544
545 let obj = guard.remove(&node_name).ok_or(io::Error::ENOENT)?;
546 if obj.get_kind() == NodeKind::File {
547 return Ok(());
548 } else {
549 guard.insert(node_name, obj);
550 return Err(io::Error::EISDIR);
551 }
552 } else if let Some(directory) = self.inner.read().await.get(&node_name) {
553 return directory.traverse_unlink(components);
554 }
555 }
556
557 Err(io::Error::EBADF)
558 },
559 None,
560 )
561 }
562
563 fn traverse_readdir(&self, components: &mut Vec<&str>) -> io::Result<Vec<DirectoryEntry>> {
564 block_on(
565 async {
566 if let Some(component) = components.pop() {
567 let node_name = String::from(component);
568
569 if let Some(directory) = self.inner.read().await.get(&node_name) {
570 directory.traverse_readdir(components)
571 } else {
572 Err(io::Error::EBADF)
573 }
574 } else {
575 let mut entries: Vec<DirectoryEntry> = Vec::new();
576 for name in self.inner.read().await.keys() {
577 entries.push(DirectoryEntry::new(name.clone()));
578 }
579
580 Ok(entries)
581 }
582 },
583 None,
584 )
585 }
586
587 fn traverse_lstat(&self, components: &mut Vec<&str>) -> io::Result<FileAttr> {
588 block_on(
589 async {
590 if let Some(component) = components.pop() {
591 let node_name = String::from(component);
592
593 if components.is_empty() {
594 if let Some(node) = self.inner.read().await.get(&node_name) {
595 return node.get_file_attributes();
596 }
597 }
598
599 if let Some(directory) = self.inner.read().await.get(&node_name) {
600 directory.traverse_lstat(components)
601 } else {
602 Err(io::Error::EBADF)
603 }
604 } else {
605 Err(io::Error::ENOSYS)
606 }
607 },
608 None,
609 )
610 }
611
612 fn traverse_stat(&self, components: &mut Vec<&str>) -> io::Result<FileAttr> {
613 block_on(
614 async {
615 if let Some(component) = components.pop() {
616 let node_name = String::from(component);
617
618 if components.is_empty() {
619 if let Some(node) = self.inner.read().await.get(&node_name) {
620 return node.get_file_attributes();
621 }
622 }
623
624 if let Some(directory) = self.inner.read().await.get(&node_name) {
625 directory.traverse_stat(components)
626 } else {
627 Err(io::Error::EBADF)
628 }
629 } else {
630 Err(io::Error::ENOSYS)
631 }
632 },
633 None,
634 )
635 }
636
637 fn traverse_mount(
638 &self,
639 components: &mut Vec<&str>,
640 obj: Box<dyn VfsNode + core::marker::Send + core::marker::Sync>,
641 ) -> io::Result<()> {
642 block_on(
643 async {
644 if let Some(component) = components.pop() {
645 let node_name = String::from(component);
646
647 if let Some(directory) = self.inner.read().await.get(&node_name) {
648 return directory.traverse_mount(components, obj);
649 }
650
651 if components.is_empty() {
652 self.inner.write().await.insert(node_name, obj);
653 return Ok(());
654 }
655 }
656
657 Err(io::Error::EBADF)
658 },
659 None,
660 )
661 }
662
663 fn traverse_open(
664 &self,
665 components: &mut Vec<&str>,
666 opt: OpenOption,
667 mode: AccessPermission,
668 ) -> io::Result<Arc<dyn ObjectInterface>> {
669 block_on(self.async_traverse_open(components, opt, mode), None)
670 }
671
672 fn traverse_create_file(
673 &self,
674 components: &mut Vec<&str>,
675 data: &'static [u8],
676 mode: AccessPermission,
677 ) -> io::Result<()> {
678 block_on(
679 async {
680 if let Some(component) = components.pop() {
681 let name = String::from(component);
682
683 if components.is_empty() {
684 let file = RomFile::new(data, mode);
685 self.inner.write().await.insert(name, Box::new(file));
686 return Ok(());
687 }
688
689 if let Some(directory) = self.inner.read().await.get(&name) {
690 return directory.traverse_create_file(components, data, mode);
691 }
692 }
693
694 Err(io::Error::ENOENT)
695 },
696 None,
697 )
698 }
699}