Skip to content

Commit 44743b9

Browse files
ext2: make_local_socket_inode
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 7e3654b commit 44743b9

File tree

2 files changed

+107
-14
lines changed

2 files changed

+107
-14
lines changed

src/aero_kernel/src/fs/ext2/group_desc.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use bit_field::BitField;
2626
use spin::RwLock;
2727

2828
use crate::fs::block::{BlockDevice, CachedAccess};
29-
use crate::fs::cache::INodeCacheItem;
3029

3130
use super::{disk, Ext2};
3231

@@ -151,7 +150,7 @@ impl GroupDescriptors {
151150
}
152151

153152
/// Allocates a new inode using the first fit allocation strategy.
154-
pub fn alloc_inode(&self) -> Option<INodeCacheItem> {
153+
pub fn alloc_inode(&self) -> Option<usize> {
155154
let fs = self.ext2.upgrade()?;
156155
let ino_per_group = fs.superblock.inodes_per_group as usize;
157156

@@ -168,7 +167,7 @@ impl GroupDescriptors {
168167
block_group.free_inodes_count -= 1;
169168
drop(descriptors); // release the lock
170169

171-
return fs.find_inode(inode_id);
170+
return Some(inode_id);
172171
}
173172

174173
None

src/aero_kernel/src/fs/ext2/mod.rs

+105-11
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ mod group_desc;
2222

2323
use core::mem::MaybeUninit;
2424

25-
use aero_syscall::MMapFlags;
25+
use aero_syscall::socket::MessageHeader;
26+
use aero_syscall::{MMapFlags, SyscallError};
2627
use alloc::boxed::Box;
2728
use alloc::string::ToString;
2829
use alloc::sync::{Arc, Weak};
@@ -33,28 +34,39 @@ use crate::fs::cache::CachedINode;
3334
use crate::fs::ext2::disk::{FileType, SuperBlock};
3435
use crate::mem::paging::{FrameAllocator, PhysFrame, FRAME_ALLOCATOR};
3536

37+
use crate::socket::unix::UnixSocket;
38+
use crate::socket::SocketAddr;
39+
3640
use self::group_desc::GroupDescriptors;
3741

3842
use super::block::{BlockDevice, CachedAccess};
3943

4044
use super::cache::{DirCacheItem, INodeCacheItem};
4145
use super::{cache, FileSystemError};
4246

43-
use super::inode::{DirEntry, INodeInterface, Metadata};
47+
use super::inode::{DirEntry, INodeInterface, Metadata, PollFlags, PollTable};
4448
use super::FileSystem;
4549

4650
pub struct INode {
4751
id: usize,
4852
fs: Weak<Ext2>,
4953
inode: RwLock<Box<disk::INode>>,
54+
// Forwards all of the inode operations to the proxy inode. Note that the
55+
// proxy inode is not saved on the disk. (e.g. This is useful for binding
56+
// a socket inode to a file).
57+
proxy: Option<Arc<dyn INodeInterface>>,
5058

5159
// TODO: Do not store this in the inode, but rather in a different
5260
// cache using the API provided by fs::cache (consider LRU only?).
5361
sref: Weak<INode>,
5462
}
5563

5664
impl INode {
57-
pub fn new(ext2: Weak<Ext2>, id: usize) -> Option<INodeCacheItem> {
65+
pub fn new(
66+
ext2: Weak<Ext2>,
67+
id: usize,
68+
proxy: Option<Arc<dyn INodeInterface>>,
69+
) -> Option<INodeCacheItem> {
5870
debug_assert!(id != 0);
5971

6072
let icache = cache::icache();
@@ -71,6 +83,7 @@ impl INode {
7183
inode: RwLock::new(inode),
7284
id,
7385
fs: ext2,
86+
proxy,
7487

7588
sref: sref.clone(),
7689
}))),
@@ -229,7 +242,12 @@ impl INode {
229242
todo!("triply indirect block")
230243
}
231244

232-
pub fn make_inode(&self, name: &str, typ: FileType) -> super::Result<INodeCacheItem> {
245+
pub fn make_inode(
246+
&self,
247+
name: &str,
248+
typ: FileType,
249+
proxy: Option<Arc<dyn INodeInterface>>,
250+
) -> super::Result<INodeCacheItem> {
233251
if !self.metadata()?.is_directory() {
234252
return Err(FileSystemError::NotSupported);
235253
}
@@ -246,6 +264,8 @@ impl INode {
246264
let fs = self.fs.upgrade().expect("ext2: filesystem was dropped");
247265

248266
let inode = fs.bgdt.alloc_inode().expect("ext2: out of inodes");
267+
let inode = fs.find_inode(inode, proxy).expect("ext2: inode not found");
268+
249269
let ext2_inode = inode.downcast_arc::<INode>().expect("ext2: invalid inode");
250270

251271
{
@@ -284,7 +304,7 @@ impl INode {
284304
name: &str,
285305
entry: &disk::DirEntry,
286306
) -> Option<DirCacheItem> {
287-
let inode = self.fs.upgrade()?.find_inode(entry.inode as usize)?;
307+
let inode = self.fs.upgrade()?.find_inode(entry.inode as usize, None)?;
288308
Some(DirEntry::new(parent, inode, name.to_string()))
289309
}
290310

@@ -358,6 +378,10 @@ impl INodeInterface for INode {
358378
}
359379

360380
fn read_at(&self, offset: usize, usr_buffer: &mut [u8]) -> super::Result<usize> {
381+
if let Some(proxy) = self.proxy.as_ref() {
382+
return proxy.read_at(offset, usr_buffer);
383+
}
384+
361385
if !self.metadata()?.is_file() {
362386
return Err(FileSystemError::NotSupported);
363387
}
@@ -374,6 +398,10 @@ impl INodeInterface for INode {
374398
}
375399

376400
fn write_at(&self, offset: usize, usr_buffer: &[u8]) -> super::Result<usize> {
401+
if let Some(proxy) = self.proxy.as_ref() {
402+
return proxy.write_at(offset, usr_buffer);
403+
}
404+
377405
if !self.metadata()?.is_file() && !self.metadata()?.is_symlink() {
378406
return Err(FileSystemError::NotSupported);
379407
}
@@ -390,23 +418,40 @@ impl INodeInterface for INode {
390418
return Err(FileSystemError::NotSupported);
391419
}
392420

393-
let inode = self.make_inode(name, FileType::Symlink)?;
421+
let inode = self.make_inode(name, FileType::Symlink, None)?;
394422
inode.write_at(0, src.name().as_bytes())?;
395423

396424
Ok(())
397425
}
398426

399427
fn truncate(&self, _size: usize) -> super::Result<()> {
428+
log::warn!("ext2::truncate is a stub!");
400429
Ok(())
401430
}
402431

403432
fn touch(&self, parent: DirCacheItem, name: &str) -> super::Result<DirCacheItem> {
404-
let inode = self.make_inode(name, FileType::File)?;
433+
if !self.metadata()?.is_directory() {
434+
return Err(FileSystemError::NotSupported);
435+
}
436+
437+
let inode = self.make_inode(name, FileType::File, None)?;
405438
Ok(DirEntry::new(parent, inode, name.to_string()))
406439
}
407440

408441
fn mkdir(&self, name: &str) -> super::Result<INodeCacheItem> {
409-
self.make_inode(name, FileType::Directory)
442+
if !self.metadata()?.is_directory() {
443+
return Err(FileSystemError::NotSupported);
444+
}
445+
446+
self.make_inode(name, FileType::Directory, None)
447+
}
448+
449+
fn make_local_socket_inode(
450+
&self,
451+
name: &str,
452+
inode: Arc<dyn INodeInterface>,
453+
) -> super::Result<INodeCacheItem> {
454+
Ok(self.make_inode(name, FileType::Socket, Some(inode))?)
410455
}
411456

412457
fn resolve_link(&self) -> super::Result<String> {
@@ -428,6 +473,8 @@ impl INodeInterface for INode {
428473
}
429474

430475
fn mmap(&self, offset: usize, size: usize, flags: MMapFlags) -> super::Result<PhysFrame> {
476+
assert!(self.proxy.is_none());
477+
431478
// TODO: support shared file mappings.
432479
assert!(!flags.contains(MMapFlags::MAP_SHARED));
433480

@@ -438,6 +485,49 @@ impl INodeInterface for INode {
438485

439486
Ok(private_cp)
440487
}
488+
489+
fn listen(&self, backlog: usize) -> Result<(), SyscallError> {
490+
if let Some(proxy) = self.proxy.as_ref() {
491+
return proxy.listen(backlog);
492+
}
493+
494+
return Err(SyscallError::EACCES);
495+
}
496+
497+
// XXX: We do not require to handle `bind` here since if this function
498+
// is being is called on an EXT2 inode then, it has already been bound.
499+
500+
fn connect(&self, address: SocketAddr, length: usize) -> super::Result<()> {
501+
if let Some(proxy) = self.proxy.as_ref() {
502+
return proxy.connect(address, length);
503+
}
504+
505+
return Err(FileSystemError::NotSupported);
506+
}
507+
508+
fn accept(&self, address: Option<&mut SocketAddr>) -> super::Result<Arc<UnixSocket>> {
509+
if let Some(proxy) = self.proxy.as_ref() {
510+
return proxy.accept(address);
511+
}
512+
513+
return Err(FileSystemError::NotSupported);
514+
}
515+
516+
fn recv(&self, message_header: &mut MessageHeader) -> super::Result<usize> {
517+
if let Some(proxy) = self.proxy.as_ref() {
518+
return proxy.recv(message_header);
519+
}
520+
521+
return Err(FileSystemError::NotSupported);
522+
}
523+
524+
fn poll(&self, table: Option<&mut PollTable>) -> super::Result<PollFlags> {
525+
if let Some(proxy) = self.proxy.as_ref() {
526+
return proxy.poll(table);
527+
}
528+
529+
return Err(FileSystemError::NotSupported);
530+
}
441531
}
442532

443533
pub struct DirEntryIter {
@@ -526,15 +616,19 @@ impl Ext2 {
526616
}))
527617
}
528618

529-
pub fn find_inode(&self, id: usize) -> Option<INodeCacheItem> {
530-
INode::new(self.sref.clone(), id)
619+
pub fn find_inode(
620+
&self,
621+
id: usize,
622+
proxy: Option<Arc<dyn INodeInterface>>,
623+
) -> Option<INodeCacheItem> {
624+
INode::new(self.sref.clone(), id, proxy)
531625
}
532626
}
533627

534628
impl FileSystem for Ext2 {
535629
fn root_dir(&self) -> DirCacheItem {
536630
let inode = self
537-
.find_inode(Ext2::ROOT_INODE_ID)
631+
.find_inode(Ext2::ROOT_INODE_ID, None)
538632
.expect("ext2: invalid filesystem (root inode not found)");
539633

540634
DirEntry::new_root(inode, String::from("/"))

0 commit comments

Comments
 (0)