vfs: add extended attributes
This commit is contained in:
parent
183ec14544
commit
cac7306719
@ -220,11 +220,14 @@ impl Inode {
|
||||
unsafe { GroupId::from_raw(self.uid as _) }
|
||||
}
|
||||
|
||||
pub fn metadata(&self) -> Metadata {
|
||||
pub fn metadata(&self, fs: &Ext2Fs, ino: u32) -> Metadata {
|
||||
Metadata {
|
||||
uid: self.user_id(),
|
||||
gid: self.group_id(),
|
||||
mode: self.mode.permissions(),
|
||||
inode: Some(ino),
|
||||
block_count: self.blocks(fs) as _,
|
||||
block_size: fs.block_size as _,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ impl CommonImpl for DirectoryNode {
|
||||
fn metadata(&self, _node: &NodeRef) -> Result<Metadata, Error> {
|
||||
let inode = block!(self.inode.get().await)??;
|
||||
let inode = inode.read();
|
||||
Ok(inode.metadata())
|
||||
Ok(inode.metadata(&self.fs, self.inode.ino()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ impl CommonImpl for RegularNode {
|
||||
fn metadata(&self, _node: &NodeRef) -> Result<Metadata, Error> {
|
||||
let inode = block!(self.inode.get().await)??;
|
||||
let inode = inode.read();
|
||||
Ok(inode.metadata())
|
||||
Ok(inode.metadata(&self.fs, self.inode.ino()))
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
|
@ -84,7 +84,7 @@ impl CommonImpl for SymlinkNode {
|
||||
fn metadata(&self, _node: &NodeRef) -> Result<Metadata, Error> {
|
||||
let inode = block!(self.inode.get().await)??;
|
||||
let inode = inode.read();
|
||||
Ok(inode.metadata())
|
||||
Ok(inode.metadata(&self.fs, self.inode.ino()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,12 @@ pub struct Metadata {
|
||||
pub gid: GroupId,
|
||||
/// Access mode of the node
|
||||
pub mode: FileMode,
|
||||
/// Filesystem-specific node number
|
||||
pub inode: Option<u32>,
|
||||
/// Filesystem-specific block size
|
||||
pub block_size: u64,
|
||||
/// Size of the node (without metadata) in units of `block_size`
|
||||
pub block_count: u64,
|
||||
}
|
||||
|
||||
struct PropertyCache {
|
||||
@ -119,6 +125,9 @@ impl Metadata {
|
||||
uid: UserId::root(),
|
||||
gid: GroupId::root(),
|
||||
mode: FileMode::new(0o755),
|
||||
block_size: 0,
|
||||
block_count: 0,
|
||||
inode: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,6 +136,9 @@ impl Metadata {
|
||||
uid: UserId::root(),
|
||||
gid: GroupId::root(),
|
||||
mode: FileMode::new(0o644),
|
||||
block_size: 0,
|
||||
block_count: 0,
|
||||
inode: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +179,6 @@ pub(crate) fn get_metadata(
|
||||
run_with_io_at(&process, at, |at, mut io| {
|
||||
let node = if path.is_empty() {
|
||||
at
|
||||
// at.ok_or(Error::InvalidArgument)?
|
||||
} else {
|
||||
io.ioctx_mut().find(Some(at), path, follow, true)?
|
||||
};
|
||||
@ -193,6 +192,9 @@ pub(crate) fn get_metadata(
|
||||
mode: metadata.mode,
|
||||
uid: metadata.uid,
|
||||
gid: metadata.gid,
|
||||
inode: metadata.inode,
|
||||
block_count: metadata.block_count,
|
||||
block_size: metadata.block_size,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -75,6 +75,14 @@ enum FileType(u32) {
|
||||
struct FileAttr {
|
||||
/// Data size for files, UNSPECIFIED for the rest
|
||||
pub size: u64,
|
||||
/// Filesystem-specific block size
|
||||
pub block_size: u64,
|
||||
/// Number of filesystem blocks (not including metadata) occupied by the entry
|
||||
pub block_count: u64,
|
||||
|
||||
/// Filesystem-specific node number
|
||||
pub inode: Option<u32>,
|
||||
|
||||
/// Entry type
|
||||
pub ty: FileType,
|
||||
/// Entry access permissions
|
||||
|
@ -5,7 +5,8 @@ use std::{
|
||||
fmt,
|
||||
fs::{read_dir, FileType, Metadata},
|
||||
io,
|
||||
path::{Path, PathBuf}, process::ExitCode,
|
||||
path::{Path, PathBuf},
|
||||
process::ExitCode,
|
||||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
@ -21,6 +22,8 @@ use humansize::{FormatSize, BINARY};
|
||||
pub struct Args {
|
||||
#[arg(short)]
|
||||
long: bool,
|
||||
#[arg(short)]
|
||||
inodes: bool,
|
||||
#[arg(short, long)]
|
||||
human_readable: bool,
|
||||
|
||||
@ -105,11 +108,25 @@ impl DisplayBit for Option<FileType> {
|
||||
impl DisplayBit for Option<Metadata> {
|
||||
fn display_bit(&self, opts: &Args, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Some(attrs) = self else {
|
||||
return write!(f, "--------- {:<8}", "???");
|
||||
write!(f, "--------- {:<12}", "???")?;
|
||||
if opts.inodes {
|
||||
write!(f, " {:<8}", "---")?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let mode = attrs.mode_ext();
|
||||
write!(f, "{} {:>8}", mode, attrs.len().display_size_with(opts))
|
||||
write!(f, "{} {:>12}", mode, attrs.len().display_size_with(opts))?;
|
||||
if opts.inodes {
|
||||
if let Some(ino) = attrs.inode() {
|
||||
write!(f, " {:>8}", ino)?;
|
||||
} else {
|
||||
write!(f, " {:>8}", "---")?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,6 +146,8 @@ impl DisplayBit for Option<Metadata> {
|
||||
|
||||
impl DisplayBit for Entry {
|
||||
fn display_bit(&self, opts: &Args, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let ino = self.attrs.as_ref().and_then(MetadataExt::inode);
|
||||
|
||||
if opts.long {
|
||||
write!(
|
||||
f,
|
||||
@ -144,6 +163,13 @@ impl DisplayBit for Entry {
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
if opts.inodes {
|
||||
if let Some(ino) = ino {
|
||||
write!(f, "{ino:<8} ")?;
|
||||
} else {
|
||||
write!(f, "{:<8} ", "---")?;
|
||||
}
|
||||
}
|
||||
f.write_str(&self.name)
|
||||
}
|
||||
}
|
||||
@ -191,9 +217,7 @@ fn list_directory(path: &Path) -> io::Result<Vec<Entry>> {
|
||||
});
|
||||
}
|
||||
|
||||
entries.sort_by(|a, b| {
|
||||
Ord::cmp(&a.name, &b.name)
|
||||
});
|
||||
entries.sort_by(|a, b| Ord::cmp(&a.name, &b.name));
|
||||
|
||||
Ok(entries)
|
||||
}
|
||||
@ -255,7 +279,7 @@ pub fn main() -> ExitCode {
|
||||
let results = run(&args);
|
||||
let code = match results.iter().any(|e| e.is_err()) {
|
||||
false => ExitCode::SUCCESS,
|
||||
true => ExitCode::FAILURE
|
||||
true => ExitCode::FAILURE,
|
||||
};
|
||||
|
||||
code
|
||||
|
Loading…
x
Reference in New Issue
Block a user