Nothing to see here, move along meow
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 8.7 kB View raw
1use crate::cap::FsRights; 2use crate::error::FsError; 3 4pub use lancer_vfs_proto::READDIR_ENTRY_SIZE; 5 6#[derive(Debug, Clone, Copy, PartialEq, Eq)] 7#[repr(u8)] 8pub enum FsOpcode { 9 Open = 1, 10 Read = 2, 11 Write = 3, 12 Close = 4, 13 Stat = 5, 14 Mkdir = 6, 15 Unlink = 7, 16 ReadDir = 8, 17 CreateSnapshot = 9, 18 DeleteSnapshot = 10, 19 Sync = 11, 20 StatFs = 12, 21 Rename = 14, 22 Truncate = 15, 23} 24 25impl FsOpcode { 26 pub const fn from_u8(v: u8) -> Option<Self> { 27 match v { 28 1 => Some(Self::Open), 29 2 => Some(Self::Read), 30 3 => Some(Self::Write), 31 4 => Some(Self::Close), 32 5 => Some(Self::Stat), 33 6 => Some(Self::Mkdir), 34 7 => Some(Self::Unlink), 35 8 => Some(Self::ReadDir), 36 9 => Some(Self::CreateSnapshot), 37 10 => Some(Self::DeleteSnapshot), 38 11 => Some(Self::Sync), 39 12 => Some(Self::StatFs), 40 14 => Some(Self::Rename), 41 15 => Some(Self::Truncate), 42 _ => None, 43 } 44 } 45} 46 47#[derive(Debug, Clone, Copy)] 48#[repr(C)] 49pub struct FsRequest { 50 pub opcode: u8, 51 pub handle: u8, 52 pub flags: u8, 53 pub _pad: u8, 54 pub tag: u32, 55 pub arg0: u64, 56 pub arg1: u64, 57 pub arg2: u64, 58} 59 60const _: () = assert!(core::mem::size_of::<FsRequest>() == 32); 61 62impl FsRequest { 63 pub const SIZE: usize = 32; 64 65 pub fn from_bytes(buf: &[u8]) -> Option<Self> { 66 match buf.len() >= Self::SIZE { 67 true => Some(unsafe { core::ptr::read_unaligned(buf.as_ptr() as *const Self) }), 68 false => None, 69 } 70 } 71 72 pub fn as_bytes(&self) -> &[u8] { 73 unsafe { core::slice::from_raw_parts(self as *const Self as *const u8, Self::SIZE) } 74 } 75 76 pub fn open(tag: u32, dir_handle: u8, mode: FsRights, name_offset: u64, name_len: u64) -> Self { 77 Self { 78 opcode: FsOpcode::Open as u8, 79 handle: dir_handle, 80 flags: mode.raw() as u8, 81 _pad: 0, 82 tag, 83 arg0: name_offset, 84 arg1: name_len, 85 arg2: 0, 86 } 87 } 88 89 pub fn read(tag: u32, handle: u8, offset: u64, len: u32, buf_offset: u32) -> Self { 90 Self { 91 opcode: FsOpcode::Read as u8, 92 handle, 93 flags: 0, 94 _pad: 0, 95 tag, 96 arg0: offset, 97 arg1: len as u64, 98 arg2: buf_offset as u64, 99 } 100 } 101 102 pub fn write(tag: u32, handle: u8, offset: u64, len: u32, buf_offset: u32) -> Self { 103 Self { 104 opcode: FsOpcode::Write as u8, 105 handle, 106 flags: 0, 107 _pad: 0, 108 tag, 109 arg0: offset, 110 arg1: len as u64, 111 arg2: buf_offset as u64, 112 } 113 } 114 115 pub fn close(tag: u32, handle: u8) -> Self { 116 Self { 117 opcode: FsOpcode::Close as u8, 118 handle, 119 flags: 0, 120 _pad: 0, 121 tag, 122 arg0: 0, 123 arg1: 0, 124 arg2: 0, 125 } 126 } 127 128 pub fn stat(tag: u32, handle: u8) -> Self { 129 Self { 130 opcode: FsOpcode::Stat as u8, 131 handle, 132 flags: 0, 133 _pad: 0, 134 tag, 135 arg0: 0, 136 arg1: 0, 137 arg2: 0, 138 } 139 } 140 141 pub fn mkdir(tag: u32, dir_handle: u8, name_offset: u64, name_len: u64) -> Self { 142 Self { 143 opcode: FsOpcode::Mkdir as u8, 144 handle: dir_handle, 145 flags: 0, 146 _pad: 0, 147 tag, 148 arg0: name_offset, 149 arg1: name_len, 150 arg2: 0, 151 } 152 } 153 154 pub fn unlink(tag: u32, dir_handle: u8, name_offset: u64, name_len: u64) -> Self { 155 Self { 156 opcode: FsOpcode::Unlink as u8, 157 handle: dir_handle, 158 flags: 0, 159 _pad: 0, 160 tag, 161 arg0: name_offset, 162 arg1: name_len, 163 arg2: 0, 164 } 165 } 166 167 pub fn readdir(tag: u32, dir_handle: u8, cursor: u64, buf_offset: u64, buf_len: u64) -> Self { 168 Self { 169 opcode: FsOpcode::ReadDir as u8, 170 handle: dir_handle, 171 flags: 0, 172 _pad: 0, 173 tag, 174 arg0: cursor, 175 arg1: buf_offset, 176 arg2: buf_len, 177 } 178 } 179 180 pub fn create_snapshot(tag: u32, name_offset: u64, name_len: u64) -> Self { 181 Self { 182 opcode: FsOpcode::CreateSnapshot as u8, 183 handle: 0, 184 flags: 0, 185 _pad: 0, 186 tag, 187 arg0: name_offset, 188 arg1: name_len, 189 arg2: 0, 190 } 191 } 192 193 pub fn delete_snapshot(tag: u32, name_offset: u64, name_len: u64) -> Self { 194 Self { 195 opcode: FsOpcode::DeleteSnapshot as u8, 196 handle: 0, 197 flags: 0, 198 _pad: 0, 199 tag, 200 arg0: name_offset, 201 arg1: name_len, 202 arg2: 0, 203 } 204 } 205 206 pub fn sync(tag: u32) -> Self { 207 Self { 208 opcode: FsOpcode::Sync as u8, 209 handle: 0, 210 flags: 0, 211 _pad: 0, 212 tag, 213 arg0: 0, 214 arg1: 0, 215 arg2: 0, 216 } 217 } 218} 219 220#[derive(Debug, Clone, Copy)] 221#[repr(C)] 222pub struct FsResponse { 223 pub opcode: u8, 224 pub status: u8, 225 pub _pad: [u8; 2], 226 pub tag: u32, 227 pub val0: u64, 228 pub val1: u64, 229} 230 231const _: () = assert!(core::mem::size_of::<FsResponse>() == 24); 232 233impl FsResponse { 234 pub const SIZE: usize = 24; 235 236 pub fn from_bytes(buf: &[u8]) -> Option<Self> { 237 match buf.len() >= Self::SIZE { 238 true => Some(unsafe { core::ptr::read_unaligned(buf.as_ptr() as *const Self) }), 239 false => None, 240 } 241 } 242 243 pub fn as_bytes(&self) -> &[u8] { 244 unsafe { core::slice::from_raw_parts(self as *const Self as *const u8, Self::SIZE) } 245 } 246 247 pub fn success(opcode: u8, tag: u32, val0: u64, val1: u64) -> Self { 248 Self { 249 opcode, 250 status: 0, 251 _pad: [0; 2], 252 tag, 253 val0, 254 val1, 255 } 256 } 257 258 pub fn error(opcode: u8, tag: u32, err: FsError) -> Self { 259 Self { 260 opcode, 261 status: fs_error_to_status(err), 262 _pad: [0; 2], 263 tag, 264 val0: 0, 265 val1: 0, 266 } 267 } 268} 269 270pub const FS_STATUS_OK: u8 = 0; 271pub const FS_STATUS_NOT_FOUND: u8 = 1; 272pub const FS_STATUS_PERMISSION_DENIED: u8 = 2; 273pub const FS_STATUS_INVALID_HANDLE: u8 = 3; 274pub const FS_STATUS_HANDLE_TABLE_FULL: u8 = 4; 275pub const FS_STATUS_IO_ERROR: u8 = 5; 276pub const FS_STATUS_DISK_FULL: u8 = 6; 277pub const FS_STATUS_NOT_A_DIRECTORY: u8 = 7; 278pub const FS_STATUS_NOT_A_FILE: u8 = 8; 279pub const FS_STATUS_IS_A_DIRECTORY: u8 = 9; 280pub const FS_STATUS_DIR_NOT_EMPTY: u8 = 10; 281pub const FS_STATUS_FILE_EXISTS: u8 = 11; 282pub const FS_STATUS_NAME_TOO_LONG: u8 = 12; 283pub const FS_STATUS_PATH_TOO_DEEP: u8 = 13; 284pub const FS_STATUS_INTEGRITY_ERROR: u8 = 14; 285pub const FS_STATUS_STALE_CAP: u8 = 15; 286pub const FS_STATUS_INVALID_OP: u8 = 16; 287pub const FS_STATUS_SYMLINK_DEPTH: u8 = 17; 288pub const FS_STATUS_CORRUPT: u8 = 18; 289pub const FS_STATUS_UNKNOWN: u8 = 255; 290 291pub fn fs_error_to_status(err: FsError) -> u8 { 292 match err { 293 FsError::NotFound | FsError::KeyNotFound => FS_STATUS_NOT_FOUND, 294 FsError::NotADirectory => FS_STATUS_NOT_A_DIRECTORY, 295 FsError::NotAFile => FS_STATUS_NOT_A_FILE, 296 FsError::IsADirectory => FS_STATUS_IS_A_DIRECTORY, 297 FsError::DirectoryNotEmpty => FS_STATUS_DIR_NOT_EMPTY, 298 FsError::FileExists => FS_STATUS_FILE_EXISTS, 299 FsError::NameTooLong => FS_STATUS_NAME_TOO_LONG, 300 FsError::PathTooDeep => FS_STATUS_PATH_TOO_DEEP, 301 FsError::IntegrityFailure => FS_STATUS_INTEGRITY_ERROR, 302 FsError::SymlinkDepthExceeded => FS_STATUS_SYMLINK_DEPTH, 303 FsError::FreemapExhausted | FsError::ReservedExhausted => FS_STATUS_DISK_FULL, 304 FsError::CorruptSuperblock | FsError::CorruptNode => FS_STATUS_CORRUPT, 305 FsError::Io(_) | FsError::CacheFull | FsError::RingFull => FS_STATUS_IO_ERROR, 306 FsError::PoolExhausted | FsError::TreeFull | FsError::DuplicateKey => FS_STATUS_IO_ERROR, 307 FsError::InvalidBlock | FsError::InvalidName | FsError::DecompressError => { 308 FS_STATUS_CORRUPT 309 } 310 FsError::InsufficientRights | FsError::StaleGeneration => FS_STATUS_PERMISSION_DENIED, 311 FsError::HandleTableFull => FS_STATUS_HANDLE_TABLE_FULL, 312 FsError::InvalidHandle => FS_STATUS_INVALID_HANDLE, 313 FsError::DoubleFree => FS_STATUS_INVALID_HANDLE, 314 } 315}