msg.rs 13 KB

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