kernel/abi/xv6/riscv64/fs/
xv6fs.rs

1use core::mem;
2
3/// xv6-style directory entry
4#[derive(Debug, Clone, Copy)]
5#[repr(C)]
6pub struct Dirent {
7    pub inum: u16,      // inode number
8    pub name: [u8; 14], // file name (null-terminated)
9}
10
11impl Dirent {
12    pub const DIRENT_SIZE: usize = mem::size_of::<Dirent>();
13
14    pub fn new(inum: u16, name: &str) -> Self {
15        let mut dirent = Dirent {
16            inum,
17            name: [0; 14],
18        };
19        
20        // Copy name, ensuring null termination
21        let name_bytes = name.as_bytes();
22        let copy_len = name_bytes.len().min(13); // Leave space for null terminator
23        dirent.name[..copy_len].copy_from_slice(&name_bytes[..copy_len]);
24        dirent.name[copy_len] = 0; // Null terminate
25        
26        dirent
27    }
28    
29    pub fn name_str(&self) -> &str {
30        // Find null terminator
31        let mut end = 0;
32        while end < self.name.len() && self.name[end] != 0 {
33            end += 1;
34        }
35        
36        // Convert to string
37        core::str::from_utf8(&self.name[..end]).unwrap_or("")
38    }
39    
40    /// Convert Dirent to byte array for reading
41    pub fn as_bytes(&self) -> &[u8] {
42        unsafe {
43            core::slice::from_raw_parts(
44                self as *const Dirent as *const u8,
45                mem::size_of::<Dirent>()
46            )
47        }
48    }
49}
50
51/// xv6-style file stat structure
52#[derive(Debug, Clone, Copy)]
53#[repr(C)]
54pub struct Stat {
55    pub dev: i32,     // File system's disk device
56    pub ino: u32,     // Inode number
57    pub file_type: u16, // Type of file (T_DIR, T_FILE, T_DEVICE)
58    pub nlink: u16,     // Number of links to file
59    pub size: u64,    // Size of file in bytes
60}
61
62// xv6 file type constants
63pub const T_DIR: u16 = 1;    // Directory
64pub const T_FILE: u16 = 2;   // File
65pub const T_DEVICE: u16 = 3; // Device