1use crate::security;
6use crate::task::{CurrentTask, Kernel};
7use crate::vfs::{
8 CacheMode, FileHandle, FileObject, FileOps, FileSystem, FileSystemHandle, FileSystemOps,
9 FileSystemOptions, FsNode, FsNodeInfo, FsNodeOps, FsStr, FsString, fs_node_impl_not_dir,
10};
11use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked};
12use starnix_types::vfs::default_statfs;
13use starnix_uapi::errors::Errno;
14use starnix_uapi::file_mode::FileMode;
15use starnix_uapi::open_flags::OpenFlags;
16use starnix_uapi::{ANON_INODE_FS_MAGIC, error, statfs};
17
18pub struct Anon {
19 name: Option<&'static str>,
22
23 is_private: bool,
24}
25
26impl FsNodeOps for Anon {
27 fs_node_impl_not_dir!();
28
29 fn create_file_ops(
30 &self,
31 _locked: &mut Locked<FileOpsCore>,
32 _node: &FsNode,
33 _current_task: &CurrentTask,
34 _flags: OpenFlags,
35 ) -> Result<Box<dyn FileOps>, Errno> {
36 error!(ENOSYS)
37 }
38
39 fn internal_name(&self, _node: &FsNode) -> Option<FsString> {
40 self.name.map(|name| format!("anon_inode:{}", name).into())
41 }
42
43 fn is_private(&self) -> bool {
44 self.is_private
45 }
46}
47
48impl Anon {
49 pub fn new_for_binder_device() -> Self {
51 Self { name: None, is_private: false }
52 }
53
54 pub fn new_for_socket(kernel_private: bool) -> Self {
56 Self { name: None, is_private: kernel_private }
57 }
58
59 pub fn new_file_extended<L>(
61 locked: &mut Locked<L>,
62 current_task: &CurrentTask,
63 ops: Box<dyn FileOps>,
64 flags: OpenFlags,
65 name: &'static str,
66 info: FsNodeInfo,
67 ) -> Result<FileHandle, Errno>
68 where
69 L: LockEqualOrBefore<FileOpsCore>,
70 {
71 let fs = anon_fs(locked, current_task.kernel());
72 let node =
73 fs.create_node_and_allocate_node_id(Anon { name: Some(name), is_private: false }, info);
74 security::fs_node_init_anon(current_task, &node, name)?;
75 Ok(FileObject::new_anonymous(locked, current_task, ops, node, flags))
76 }
77
78 pub fn new_file<L>(
80 locked: &mut Locked<L>,
81 current_task: &CurrentTask,
82 ops: Box<dyn FileOps>,
83 flags: OpenFlags,
84 name: &'static str,
85 ) -> Result<FileHandle, Errno>
86 where
87 L: LockEqualOrBefore<FileOpsCore>,
88 {
89 Self::new_file_extended(
90 locked,
91 current_task,
92 ops,
93 flags,
94 name,
95 FsNodeInfo::new(FileMode::from_bits(0o600), current_task.current_fscred()),
96 )
97 }
98
99 pub fn new_private_file<L>(
102 locked: &mut Locked<L>,
103 current_task: &CurrentTask,
104 ops: Box<dyn FileOps>,
105 flags: OpenFlags,
106 name: &'static str,
107 ) -> FileHandle
108 where
109 L: LockEqualOrBefore<FileOpsCore>,
110 {
111 Self::new_private_file_extended(
112 locked,
113 current_task,
114 ops,
115 flags,
116 name,
117 FsNodeInfo::new(FileMode::from_bits(0o600), current_task.current_fscred()),
118 )
119 }
120
121 pub fn new_private_file_extended<L>(
123 locked: &mut Locked<L>,
124 current_task: &CurrentTask,
125 ops: Box<dyn FileOps>,
126 flags: OpenFlags,
127 name: &'static str,
128 info: FsNodeInfo,
129 ) -> FileHandle
130 where
131 L: LockEqualOrBefore<FileOpsCore>,
132 {
133 let fs = anon_fs(locked, current_task.kernel());
134 let node =
135 fs.create_node_and_allocate_node_id(Anon { name: Some(name), is_private: true }, info);
136 security::fs_node_init_anon(current_task, &node, name)
137 .expect("Private anon_inode creation cannot fail");
138 FileObject::new_anonymous(locked, current_task, ops, node, flags)
139 }
140}
141
142struct AnonFs;
143impl FileSystemOps for AnonFs {
144 fn statfs(
145 &self,
146 _locked: &mut Locked<FileOpsCore>,
147 _fs: &FileSystem,
148 _current_task: &CurrentTask,
149 ) -> Result<statfs, Errno> {
150 Ok(default_statfs(ANON_INODE_FS_MAGIC))
151 }
152 fn name(&self) -> &'static FsStr {
153 "anon_inodefs".into()
154 }
155}
156pub fn anon_fs<L>(locked: &mut Locked<L>, kernel: &Kernel) -> FileSystemHandle
157where
158 L: LockEqualOrBefore<FileOpsCore>,
159{
160 struct AnonFsHandle(FileSystemHandle);
161
162 kernel
163 .expando
164 .get_or_init(|| {
165 let fs = FileSystem::new(
166 locked,
167 kernel,
168 CacheMode::Uncached,
169 AnonFs,
170 FileSystemOptions::default(),
171 )
172 .expect("anonfs constructed with valid options");
173 AnonFsHandle(fs)
174 })
175 .0
176 .clone()
177}