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