starnix_core/vfs/
xattr.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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}