starnix_core/vfs/
xattr.rs1use crate::vfs::{FsStr, FsString, XattrOp, XattrStorage};
6use starnix_rcu::rcu_hash_map::Entry;
7use starnix_rcu::{RcuHashMap, RcuReadScope};
8use starnix_sync::{FileOpsCore, Locked};
9use starnix_uapi::errors::Errno;
10use starnix_uapi::{errno, error};
11
12#[derive(Default)]
13pub struct MemoryXattrStorage {
14 xattrs: RcuHashMap<FsString, FsString>,
15}
16
17impl XattrStorage for MemoryXattrStorage {
18 fn get_xattr(
19 &self,
20 _locked: &mut Locked<FileOpsCore>,
21 name: &FsStr,
22 ) -> Result<FsString, Errno> {
23 self.xattrs.get(&RcuReadScope::new(), name).cloned().ok_or_else(|| errno!(ENODATA))
24 }
25
26 fn set_xattr(
27 &self,
28 _locked: &mut Locked<FileOpsCore>,
29 name: &FsStr,
30 value: &FsStr,
31 op: XattrOp,
32 ) -> Result<(), Errno> {
33 let mut xattrs = self.xattrs.lock();
34 match xattrs.entry(name.to_owned()) {
35 Entry::Vacant(_) if op == XattrOp::Replace => return error!(ENODATA),
36 Entry::Occupied(_) if op == XattrOp::Create => return error!(EEXIST),
37 Entry::Vacant(v) => {
38 v.insert(value.to_owned());
39 }
40 Entry::Occupied(mut o) => {
41 o.insert(value.to_owned());
42 }
43 };
44 Ok(())
45 }
46
47 fn remove_xattr(&self, _locked: &mut Locked<FileOpsCore>, name: &FsStr) -> Result<(), Errno> {
48 let mut xattrs = self.xattrs.lock();
49 if xattrs.remove(name).is_none() {
50 return error!(ENODATA);
51 }
52 Ok(())
53 }
54
55 fn list_xattrs(&self, _locked: &mut Locked<FileOpsCore>) -> Result<Vec<FsString>, Errno> {
56 Ok(self.xattrs.keys(&RcuReadScope::new()).cloned().collect())
57 }
58}