Skip to main content

btrfs_fs/
stat.rs

1//! POSIX-style inode metadata returned by [`crate::Filesystem::getattr`].
2
3use crate::{FileKind, Inode};
4use btrfs_disk::items::{InodeItem, Timespec};
5use std::time::{Duration, SystemTime, UNIX_EPOCH};
6
7/// Convert an on-disk btrfs [`Timespec`] to a [`SystemTime`].
8#[must_use]
9pub fn to_system_time(ts: &Timespec) -> SystemTime {
10    UNIX_EPOCH + Duration::new(ts.sec, ts.nsec)
11}
12
13/// POSIX-style file metadata.
14///
15/// Mirrors the fields a `stat(2)` caller cares about, plus the btrfs
16/// btime. The struct is FUSE-independent: a FUSE adapter can build a
17/// `fuser::FileAttr` from it with a small mapping, and a non-FUSE
18/// embedder (offline tools, tests) can read the fields directly.
19#[derive(Debug, Clone, Copy)]
20pub struct Stat {
21    pub ino: Inode,
22    pub kind: FileKind,
23    pub size: u64,
24    pub blocks: u64,
25    pub atime: SystemTime,
26    pub mtime: SystemTime,
27    pub ctime: SystemTime,
28    /// btrfs creation time (`otime`), exposed for callers that surface
29    /// `birthtime` / `crtime`.
30    pub btime: SystemTime,
31    /// Permission bits (mode & 0o7777).
32    pub perm: u16,
33    pub nlink: u32,
34    pub uid: u32,
35    pub gid: u32,
36    pub rdev: u32,
37    pub blksize: u32,
38}
39
40impl Stat {
41    /// Build a [`Stat`] from a parsed [`InodeItem`].
42    #[must_use]
43    pub fn from_inode(ino: Inode, item: &InodeItem, blksize: u32) -> Self {
44        #[allow(clippy::cast_possible_truncation)]
45        let perm = (item.mode & 0o7777) as u16;
46        #[allow(clippy::cast_possible_truncation)]
47        // rdev fits in 20 bits (major:12 + minor:8)
48        let rdev = item.rdev as u32;
49        Self {
50            ino,
51            kind: FileKind::from_mode(item.mode),
52            size: item.size,
53            blocks: item.nbytes / 512,
54            atime: to_system_time(&item.atime),
55            mtime: to_system_time(&item.mtime),
56            ctime: to_system_time(&item.ctime),
57            btime: to_system_time(&item.otime),
58            perm,
59            nlink: item.nlink,
60            uid: item.uid,
61            gid: item.gid,
62            rdev,
63            blksize,
64        }
65    }
66}