1use fuser::{FileType, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry, ReplyWrite};
4use libc::ENOENT;
5
6use super::{RagFs, TTL, reply_file_bytes};
7use crate::inode::{
8 OPS_BATCH_INO, OPS_CREATE_INO, OPS_DELETE_INO, OPS_DIR_INO, OPS_MOVE_INO, OPS_RESULT_INO,
9 RAGFS_DIR_INO,
10};
11
12impl RagFs {
13 pub(crate) fn lookup_ops_dir(&mut self, name_str: &str, reply: ReplyEntry) {
14 match name_str {
15 ".create" => {
16 let attr = self.make_attr(OPS_CREATE_INO, FileType::RegularFile, 0);
17 reply.entry(&TTL, &attr, 0);
18 }
19 ".delete" => {
20 let attr = self.make_attr(OPS_DELETE_INO, FileType::RegularFile, 0);
21 reply.entry(&TTL, &attr, 0);
22 }
23 ".move" => {
24 let attr = self.make_attr(OPS_MOVE_INO, FileType::RegularFile, 0);
25 reply.entry(&TTL, &attr, 0);
26 }
27 ".batch" => {
28 let attr = self.make_attr(OPS_BATCH_INO, FileType::RegularFile, 0);
29 reply.entry(&TTL, &attr, 0);
30 }
31 ".result" => {
32 let content = self.runtime.block_on(self.ops_manager.get_last_result());
33 let attr =
34 self.make_attr(OPS_RESULT_INO, FileType::RegularFile, content.len() as u64);
35 let mut cache = self.runtime.block_on(self.content_cache.write());
36 cache.insert(OPS_RESULT_INO, content);
37 reply.entry(&TTL, &attr, 0);
38 }
39 _ => reply.error(ENOENT),
40 }
41 }
42
43 pub(crate) fn getattr_ops(&mut self, ino: u64, reply: ReplyAttr) {
44 match ino {
45 OPS_DIR_INO => {
46 let attr = self.make_attr(ino, FileType::Directory, 0);
47 reply.attr(&TTL, &attr);
48 }
49 OPS_CREATE_INO | OPS_DELETE_INO | OPS_MOVE_INO | OPS_BATCH_INO => {
50 let attr = self.make_attr(ino, FileType::RegularFile, 0);
51 reply.attr(&TTL, &attr);
52 }
53 OPS_RESULT_INO => {
54 let content = self.runtime.block_on(self.ops_manager.get_last_result());
55 let size = content.len() as u64;
56 let mut cache = self.runtime.block_on(self.content_cache.write());
57 cache.insert(OPS_RESULT_INO, content);
58 let attr = self.make_attr(ino, FileType::RegularFile, size);
59 reply.attr(&TTL, &attr);
60 }
61 _ => reply.error(ENOENT),
62 }
63 }
64
65 pub(crate) fn read_ops(&mut self, ino: u64, offset: i64, size: u32, reply: ReplyData) {
66 match ino {
67 OPS_RESULT_INO => {
68 let content = self.runtime.block_on(self.ops_manager.get_last_result());
69 reply_file_bytes(reply, &content, offset, size);
70 }
71 OPS_CREATE_INO | OPS_DELETE_INO | OPS_MOVE_INO | OPS_BATCH_INO => {
72 reply.data(&[]);
73 }
74 _ => reply.error(ENOENT),
75 }
76 }
77
78 pub(crate) fn readdir_ops(&mut self, offset: i64, mut reply: ReplyDirectory) {
79 let entries = [
80 (OPS_DIR_INO, FileType::Directory, "."),
81 (RAGFS_DIR_INO, FileType::Directory, ".."),
82 (OPS_CREATE_INO, FileType::RegularFile, ".create"),
83 (OPS_DELETE_INO, FileType::RegularFile, ".delete"),
84 (OPS_MOVE_INO, FileType::RegularFile, ".move"),
85 (OPS_BATCH_INO, FileType::RegularFile, ".batch"),
86 (OPS_RESULT_INO, FileType::RegularFile, ".result"),
87 ];
88
89 for (i, (ino, kind, name)) in entries.iter().enumerate().skip(offset as usize) {
90 if reply.add(*ino, (i + 1) as i64, *kind, name) {
91 break;
92 }
93 }
94 reply.ok();
95 }
96
97 pub(crate) fn write_ops(&mut self, ino: u64, data: &[u8], reply: ReplyWrite) {
98 if ino == OPS_CREATE_INO {
99 let data_str = String::from_utf8_lossy(data).to_string();
100 let ops_manager = self.ops_manager.clone();
101 self.runtime.block_on(async move {
102 ops_manager.parse_and_create(&data_str).await;
103 });
104 reply.written(data.len() as u32);
105 return;
106 }
107 if ino == OPS_DELETE_INO {
108 let data_str = String::from_utf8_lossy(data).to_string();
109 let ops_manager = self.ops_manager.clone();
110 self.runtime.block_on(async move {
111 ops_manager.parse_and_delete(&data_str).await;
112 });
113 reply.written(data.len() as u32);
114 return;
115 }
116 if ino == OPS_MOVE_INO {
117 let data_str = String::from_utf8_lossy(data).to_string();
118 let ops_manager = self.ops_manager.clone();
119 self.runtime.block_on(async move {
120 ops_manager.parse_and_move(&data_str).await;
121 });
122 reply.written(data.len() as u32);
123 return;
124 }
125 if ino == OPS_BATCH_INO {
126 let data_str = String::from_utf8_lossy(data).to_string();
127 let ops_manager = self.ops_manager.clone();
128 self.runtime.block_on(async move {
129 ops_manager.parse_and_batch(&data_str).await;
130 });
131 reply.written(data.len() as u32);
132 }
133 }
134}