msg.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. // SPDX-License-Identifier: AGPL-3.0-or-later
  2. use super::{Handle, Inode};
  3. use btlib::{
  4. bterr,
  5. crypto::{AsymKeyPub, Encrypt},
  6. BlockMetaSecrets, DirEntry, DirEntryKind, Epoch, IssuedProcRec, Principal,
  7. };
  8. use btmsg::CallMsg;
  9. use core::time::Duration;
  10. use paste::paste;
  11. use serde::{Deserialize, Serialize};
  12. use std::{
  13. fmt::Display,
  14. io,
  15. ops::{BitOr, BitOrAssign},
  16. };
  17. #[derive(Serialize, Deserialize)]
  18. pub enum FsMsg<'a> {
  19. #[serde(borrow)]
  20. Lookup(Lookup<'a>),
  21. #[serde(borrow)]
  22. Create(Create<'a>),
  23. Open(Open),
  24. Read(Read),
  25. #[serde(borrow)]
  26. Write(Write<&'a [u8]>),
  27. Flush(Flush),
  28. ReadDir(ReadDir),
  29. #[serde(borrow)]
  30. Link(Link<'a>),
  31. #[serde(borrow)]
  32. Unlink(Unlink<'a>),
  33. ReadMeta(ReadMeta),
  34. WriteMeta(WriteMeta),
  35. Allocate(Allocate),
  36. Close(Close),
  37. Forget(Forget),
  38. Lock(Lock),
  39. Unlock(Unlock),
  40. AddReadcap(AddReadcap),
  41. GrantAccess(GrantAccess),
  42. }
  43. #[derive(Serialize, Deserialize)]
  44. pub enum FsReply<'a> {
  45. Ack(()),
  46. Lookup(LookupReply),
  47. Create(CreateReply),
  48. Open(OpenReply),
  49. #[serde(borrow)]
  50. Read(ReadReply<'a>),
  51. Write(WriteReply),
  52. ReadDir(ReadDirReply),
  53. Link(LinkReply),
  54. ReadMeta(ReadMetaReply),
  55. WriteMeta(WriteMetaReply),
  56. }
  57. impl<'a> CallMsg<'a> for FsMsg<'a> {
  58. type Reply<'b> = FsReply<'b>;
  59. }
  60. #[derive(Debug, Serialize, Deserialize)]
  61. pub enum FsError {
  62. Other,
  63. }
  64. impl Display for FsError {
  65. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  66. match self {
  67. Self::Other => write!(f, "uncategorized error"),
  68. }
  69. }
  70. }
  71. impl std::error::Error for FsError {}
  72. #[repr(u64)]
  73. /// An enumeration of special Inodes.
  74. pub enum SpecInodes {
  75. RootDir = 1,
  76. Sb = 2,
  77. FirstFree = 11,
  78. }
  79. impl SpecInodes {
  80. pub fn value(self) -> Inode {
  81. self as Inode
  82. }
  83. }
  84. impl From<SpecInodes> for Inode {
  85. fn from(special: SpecInodes) -> Self {
  86. special.value()
  87. }
  88. }
  89. #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
  90. #[repr(u32)] // This type needs to match `libc::mode_t`.
  91. /// The type of a file (regular, directory, etc).
  92. pub enum FileType {
  93. /// Directory.
  94. Dir = libc::S_IFDIR,
  95. /// Regular file.
  96. Reg = libc::S_IFREG,
  97. }
  98. impl FileType {
  99. /// Returns the underlying mode bits for this file type.
  100. pub fn value(self) -> libc::mode_t {
  101. self as libc::mode_t
  102. }
  103. /// Attempts to convert the given mode bits into a `FileType` enum value.
  104. pub fn from_value(value: libc::mode_t) -> btlib::Result<Self> {
  105. if (value & libc::S_IFDIR) != 0 {
  106. return Ok(FileType::Dir);
  107. }
  108. if (value & libc::S_IFREG) != 0 {
  109. return Ok(FileType::Reg);
  110. }
  111. Err(bterr!("unknown file type: 0o{value:0o}"))
  112. }
  113. pub fn dir_entry_kind(self) -> DirEntryKind {
  114. match self {
  115. Self::Dir => DirEntryKind::Directory,
  116. Self::Reg => DirEntryKind::File,
  117. }
  118. }
  119. }
  120. impl From<FileType> for libc::mode_t {
  121. fn from(file_type: FileType) -> Self {
  122. file_type.value()
  123. }
  124. }
  125. impl TryFrom<libc::mode_t> for FileType {
  126. type Error = btlib::Error;
  127. fn try_from(value: libc::mode_t) -> btlib::Result<Self> {
  128. Self::from_value(value)
  129. }
  130. }
  131. impl From<FileType> for DirEntryKind {
  132. fn from(value: FileType) -> Self {
  133. value.dir_entry_kind()
  134. }
  135. }
  136. impl BitOr<libc::mode_t> for FileType {
  137. type Output = libc::mode_t;
  138. fn bitor(self, rhs: libc::mode_t) -> Self::Output {
  139. self.value() | rhs
  140. }
  141. }
  142. #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
  143. #[repr(i32)]
  144. /// The generators for the group of [Flag]s. These are mostly copied from [libc], save for
  145. /// several custom values. Note that the presence of a flag in this enum does not guarantee
  146. /// it's supported.
  147. pub enum FlagValue {
  148. // Standard flags.
  149. ReadOnly = libc::O_RDONLY,
  150. WriteOnly = libc::O_WRONLY,
  151. ReadWrite = libc::O_RDWR,
  152. AccMode = libc::O_ACCMODE,
  153. Create = libc::O_CREAT,
  154. Exclusive = libc::O_EXCL,
  155. NoCtty = libc::O_NOCTTY,
  156. Truncate = libc::O_TRUNC,
  157. Append = libc::O_APPEND,
  158. NonBlock = libc::O_NONBLOCK,
  159. Dsync = libc::O_DSYNC,
  160. Async = libc::O_ASYNC,
  161. Direct = libc::O_DIRECT,
  162. Directory = libc::O_DIRECTORY,
  163. NoFollow = libc::O_NOFOLLOW,
  164. NoAtime = libc::O_NOATIME,
  165. CloseExec = libc::O_CLOEXEC,
  166. Rsync = libc::O_RSYNC,
  167. Path = libc::O_PATH,
  168. TmpFile = libc::O_TMPFILE,
  169. // Custom flags.
  170. /// Indicates that a process block should be created.
  171. Process = 0x01000000,
  172. /// Indicates that a server block be created.
  173. Server = 0x02000000,
  174. }
  175. impl FlagValue {
  176. pub const fn value(self) -> i32 {
  177. self as i32
  178. }
  179. }
  180. impl Copy for FlagValue {}
  181. impl From<FlagValue> for i32 {
  182. fn from(flag_value: FlagValue) -> Self {
  183. flag_value.value()
  184. }
  185. }
  186. impl BitOr for FlagValue {
  187. type Output = Flags;
  188. fn bitor(self, rhs: Self) -> Self::Output {
  189. Flags::new(self.value() | rhs.value())
  190. }
  191. }
  192. #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
  193. /// A wrapper type around [i32] with convenience methods for checking if `libc::O_*`
  194. /// flags have been set.
  195. pub struct Flags(i32);
  196. impl Copy for Flags {}
  197. impl Flags {
  198. pub const fn new(value: i32) -> Self {
  199. Self(value)
  200. }
  201. pub const fn value(self) -> i32 {
  202. self.0
  203. }
  204. /// Returns true if and only if the given open flags allow the file to be written to.
  205. pub const fn writeable(self) -> bool {
  206. const MASK: i32 = FlagValue::ReadWrite.value() | FlagValue::WriteOnly.value();
  207. self.0 & MASK != 0
  208. }
  209. pub const fn readable(self) -> bool {
  210. !self.write_only()
  211. }
  212. pub const fn read_only(self) -> bool {
  213. self.0 == FlagValue::ReadOnly.value()
  214. }
  215. pub const fn write_only(self) -> bool {
  216. self.0 & FlagValue::WriteOnly.value() != 0
  217. }
  218. pub const fn directory(self) -> bool {
  219. self.0 & FlagValue::Directory.value() != 0
  220. }
  221. pub const fn process(self) -> bool {
  222. self.0 & FlagValue::Process.value() != 0
  223. }
  224. pub const fn server(self) -> bool {
  225. self.0 & FlagValue::Server.value() != 0
  226. }
  227. pub fn assert_readable(self) -> Result<(), io::Error> {
  228. if !self.readable() {
  229. Err(io::Error::from_raw_os_error(libc::EACCES))
  230. } else {
  231. Ok(())
  232. }
  233. }
  234. pub fn assert_writeable(self) -> Result<(), io::Error> {
  235. if !self.writeable() {
  236. Err(io::Error::from_raw_os_error(libc::EACCES))
  237. } else {
  238. Ok(())
  239. }
  240. }
  241. }
  242. impl From<i32> for Flags {
  243. fn from(value: i32) -> Self {
  244. Self::new(value)
  245. }
  246. }
  247. impl From<Flags> for i32 {
  248. fn from(flags: Flags) -> Self {
  249. flags.value()
  250. }
  251. }
  252. impl From<FlagValue> for Flags {
  253. fn from(flag_value: FlagValue) -> Self {
  254. Self::new(flag_value.value())
  255. }
  256. }
  257. impl BitOr<Flags> for Flags {
  258. type Output = Flags;
  259. fn bitor(self, rhs: Flags) -> Self::Output {
  260. Self::new(self.value() | rhs.value())
  261. }
  262. }
  263. impl BitOr<FlagValue> for Flags {
  264. type Output = Flags;
  265. fn bitor(self, rhs: FlagValue) -> Self::Output {
  266. Self::new(self.value() | rhs.value())
  267. }
  268. }
  269. impl Display for Flags {
  270. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  271. self.value().fmt(f)
  272. }
  273. }
  274. impl Default for Flags {
  275. fn default() -> Self {
  276. Self::new(0)
  277. }
  278. }
  279. #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Hash, Default)]
  280. pub struct Attrs {
  281. pub mode: u32,
  282. pub uid: u32,
  283. pub gid: u32,
  284. pub atime: Epoch,
  285. pub mtime: Epoch,
  286. pub ctime: Epoch,
  287. pub tags: Vec<(String, Vec<u8>)>,
  288. }
  289. #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Hash)]
  290. /// A type for indicating which fields in [Attrs] have been set and which should be ignored. This
  291. /// method was chosen over using [Option] for greater efficiency on the wire.
  292. pub struct AttrsSet(u16);
  293. macro_rules! field {
  294. ($index:expr, $name:ident) => {
  295. pub const $name: AttrsSet = AttrsSet::new(1 << $index);
  296. paste! {
  297. pub fn [<$name:lower>](self) -> bool {
  298. const MASK: u16 = 1 << $index;
  299. self.0 & MASK != 0
  300. }
  301. }
  302. };
  303. }
  304. impl AttrsSet {
  305. field!(0, MODE);
  306. field!(1, UID);
  307. field!(2, GID);
  308. field!(3, ATIME);
  309. field!(4, MTIME);
  310. field!(5, CTIME);
  311. pub const ALL: Self = Self::new(
  312. Self::MODE.0 | Self::UID.0 | Self::GID.0 | Self::ATIME.0 | Self::MTIME.0 | Self::CTIME.0,
  313. );
  314. pub const fn new(value: u16) -> Self {
  315. Self(value)
  316. }
  317. pub const fn none() -> Self {
  318. Self(0)
  319. }
  320. pub const fn value(self) -> u16 {
  321. self.0
  322. }
  323. }
  324. impl Copy for AttrsSet {}
  325. impl From<u16> for AttrsSet {
  326. fn from(value: u16) -> Self {
  327. Self::new(value)
  328. }
  329. }
  330. impl From<AttrsSet> for u16 {
  331. fn from(attr: AttrsSet) -> Self {
  332. attr.value()
  333. }
  334. }
  335. impl BitOr<Self> for AttrsSet {
  336. type Output = Self;
  337. fn bitor(self, rhs: Self) -> Self::Output {
  338. AttrsSet::new(self.value() | rhs.value())
  339. }
  340. }
  341. impl BitOrAssign<Self> for AttrsSet {
  342. fn bitor_assign(&mut self, rhs: Self) {
  343. self.0 |= rhs.0
  344. }
  345. }
  346. #[derive(Serialize, Deserialize)]
  347. pub struct Entry {
  348. pub attr: BlockMetaSecrets,
  349. pub attr_timeout: Duration,
  350. pub entry_timeout: Duration,
  351. }
  352. #[derive(Serialize, Deserialize)]
  353. pub struct Lookup<'a> {
  354. pub parent: Inode,
  355. pub name: &'a str,
  356. }
  357. #[derive(Serialize, Deserialize)]
  358. pub struct LookupReply {
  359. pub inode: Inode,
  360. pub generation: u64,
  361. pub entry: Entry,
  362. }
  363. #[derive(Serialize, Deserialize)]
  364. pub struct Create<'a> {
  365. pub parent: Inode,
  366. pub name: &'a str,
  367. pub flags: Flags,
  368. pub mode: u32,
  369. pub umask: u32,
  370. }
  371. #[derive(Serialize, Deserialize)]
  372. pub struct CreateReply {
  373. pub inode: Inode,
  374. pub handle: Handle,
  375. pub entry: Entry,
  376. }
  377. #[derive(Serialize, Deserialize)]
  378. pub struct Open {
  379. pub inode: Inode,
  380. pub flags: Flags,
  381. }
  382. #[derive(Serialize, Deserialize)]
  383. pub struct OpenReply {
  384. pub handle: Handle,
  385. }
  386. #[derive(Serialize, Deserialize)]
  387. pub struct Read {
  388. pub inode: Inode,
  389. pub handle: Handle,
  390. pub offset: u64,
  391. pub size: u64,
  392. }
  393. #[derive(Serialize, Deserialize)]
  394. pub struct ReadReply<'a> {
  395. pub data: &'a [u8],
  396. }
  397. #[derive(Serialize, Deserialize)]
  398. pub struct Write<R> {
  399. pub inode: Inode,
  400. pub handle: Handle,
  401. pub offset: u64,
  402. pub data: R,
  403. }
  404. #[derive(Serialize, Deserialize)]
  405. pub struct WriteReply {
  406. pub written: u64,
  407. }
  408. #[derive(Serialize, Deserialize)]
  409. pub struct Flush {
  410. pub inode: Inode,
  411. pub handle: Handle,
  412. }
  413. #[derive(Serialize, Deserialize)]
  414. pub struct ReadDir {
  415. pub inode: Inode,
  416. pub handle: Handle,
  417. /// The maximum number of directory entries to return in a single response. A value of 0
  418. /// indicates there is no limit. Note that the server may impose it's own limit.
  419. pub limit: u32,
  420. /// An opaque value which the server uses to keep track of the client's position in reading
  421. /// the directory. A value of 0 indicates the directory is to be iterated from the beginning.
  422. pub state: u64,
  423. }
  424. #[derive(Serialize, Deserialize)]
  425. pub struct ReadDirReply {
  426. pub entries: Vec<(String, DirEntry)>,
  427. /// This is the value to pass in a subsequent [ReadDir] message to continue reading this
  428. /// directory. A value of 0 indicates that all entries have been returned.
  429. pub new_state: u64,
  430. }
  431. #[derive(Serialize, Deserialize)]
  432. pub struct Link<'a> {
  433. pub inode: Inode,
  434. pub new_parent: Inode,
  435. pub name: &'a str,
  436. }
  437. #[derive(Serialize, Deserialize)]
  438. pub struct LinkReply {
  439. pub entry: Entry,
  440. }
  441. #[derive(Serialize, Deserialize)]
  442. pub struct Unlink<'a> {
  443. pub parent: Inode,
  444. pub name: &'a str,
  445. }
  446. #[derive(Serialize, Deserialize)]
  447. pub struct ReadMeta {
  448. pub inode: Inode,
  449. pub handle: Option<Handle>,
  450. }
  451. #[derive(Serialize, Deserialize)]
  452. pub struct ReadMetaReply {
  453. pub attrs: BlockMetaSecrets,
  454. pub valid_for: Duration,
  455. }
  456. #[derive(Serialize, Deserialize)]
  457. pub struct WriteMeta {
  458. pub inode: Inode,
  459. pub handle: Option<Handle>,
  460. pub attrs: Attrs,
  461. /// The bits in this value indicate which fields in `attrs` have been initialized.
  462. pub attrs_set: AttrsSet,
  463. }
  464. #[derive(Serialize, Deserialize)]
  465. pub struct WriteMetaReply {
  466. pub attrs: BlockMetaSecrets,
  467. pub valid_for: Duration,
  468. }
  469. #[derive(Serialize, Deserialize)]
  470. pub struct Allocate {
  471. pub inode: Inode,
  472. pub handle: Handle,
  473. pub offset: Option<u64>,
  474. pub size: u64,
  475. }
  476. #[derive(Serialize, Deserialize)]
  477. pub struct Close {
  478. pub inode: Inode,
  479. pub handle: Handle,
  480. }
  481. #[derive(Serialize, Deserialize)]
  482. pub struct Forget {
  483. pub inode: Inode,
  484. pub count: u64,
  485. }
  486. #[derive(Serialize, Deserialize)]
  487. pub struct LockDesc {
  488. pub offset: u64,
  489. pub size: u64,
  490. pub exclusive: bool,
  491. }
  492. #[derive(Serialize, Deserialize)]
  493. pub struct Lock {
  494. pub inode: Inode,
  495. pub handle: Handle,
  496. pub desc: LockDesc,
  497. }
  498. #[derive(Serialize, Deserialize)]
  499. pub struct Unlock {
  500. pub inode: Inode,
  501. pub handle: Handle,
  502. }
  503. #[derive(Serialize, Deserialize)]
  504. pub struct AddReadcap {
  505. pub inode: Inode,
  506. pub handle: Handle,
  507. pub principal: Principal,
  508. pub enc_key: AsymKeyPub<Encrypt>,
  509. }
  510. #[derive(Serialize, Deserialize)]
  511. pub struct GrantAccess {
  512. pub inode: Inode,
  513. pub record: IssuedProcRec,
  514. }