Blame


1 4338ef2e 2024-05-18 benni #include <fuse_opt.h>
2 4338ef2e 2024-05-18 benni #include <libgen.h>
3 4338ef2e 2024-05-18 benni #include <unistd.h>
4 4338ef2e 2024-05-18 benni #include <string.h>
5 4338ef2e 2024-05-18 benni #include <stdlib.h>
6 4338ef2e 2024-05-18 benni #include <stdio.h>
7 4338ef2e 2024-05-18 benni #include <errno.h>
8 4338ef2e 2024-05-18 benni #include <fuse.h>
9 4338ef2e 2024-05-18 benni #include <err.h>
10 4338ef2e 2024-05-18 benni #include "sufs.h"
11 4338ef2e 2024-05-18 benni
12 4338ef2e 2024-05-18 benni #define MIN(a, b) ((a) < (b) ? (a) : (b))
13 4338ef2e 2024-05-18 benni #define MAX(a, b) ((a) > (b) ? (a) : (b))
14 4338ef2e 2024-05-18 benni
15 4338ef2e 2024-05-18 benni enum {
16 4338ef2e 2024-05-18 benni KEY_VERSION,
17 4338ef2e 2024-05-18 benni KEY_HELP,
18 4338ef2e 2024-05-18 benni };
19 4338ef2e 2024-05-18 benni
20 4338ef2e 2024-05-18 benni static const struct fuse_opt opts[] = {
21 4338ef2e 2024-05-18 benni FUSE_OPT_KEY("-V", KEY_VERSION),
22 4338ef2e 2024-05-18 benni FUSE_OPT_KEY("-h", KEY_HELP),
23 4338ef2e 2024-05-18 benni FUSE_OPT_END
24 4338ef2e 2024-05-18 benni };
25 4338ef2e 2024-05-18 benni static struct sufs_superblock sb;
26 4338ef2e 2024-05-18 benni static char *buffer, *dbuffer;
27 4338ef2e 2024-05-18 benni static int fd;
28 4338ef2e 2024-05-18 benni
29 4338ef2e 2024-05-18 benni static void write_inode (uint64_t, const struct sufs_inode *);
30 4338ef2e 2024-05-18 benni static struct sufs_inode read_inode (uint64_t ino);
31 4338ef2e 2024-05-18 benni
32 4338ef2e 2024-05-18 benni void read_block (uint64_t b, char *d)
33 4338ef2e 2024-05-18 benni {
34 4338ef2e 2024-05-18 benni printf ("read_block(%zu);\n", (size_t)b);
35 4338ef2e 2024-05-18 benni if (lseek (fd, b * sb.bsize, SEEK_SET) < 0)
36 4338ef2e 2024-05-18 benni err (1, "read_block(): lseek()");
37 4338ef2e 2024-05-18 benni if (read (fd, d, sb.bsize) != sb.bsize)
38 4338ef2e 2024-05-18 benni err (1, "read_block(): read()");
39 4338ef2e 2024-05-18 benni }
40 4338ef2e 2024-05-18 benni
41 4338ef2e 2024-05-18 benni void write_block (uint64_t b, const char *d)
42 4338ef2e 2024-05-18 benni {
43 4338ef2e 2024-05-18 benni printf ("write_block(%zu);\n", (size_t)b);
44 4338ef2e 2024-05-18 benni if (lseek (fd, b * sb.bsize, SEEK_SET) < 0)
45 4338ef2e 2024-05-18 benni err (1, "write_block(): lseek()");
46 4338ef2e 2024-05-18 benni if (write (fd, d, sb.bsize) != sb.bsize)
47 4338ef2e 2024-05-18 benni err (1, "write_block(): read()");
48 4338ef2e 2024-05-18 benni }
49 4338ef2e 2024-05-18 benni
50 4338ef2e 2024-05-18 benni static uint64_t alloc_bitmap (uint64_t begin, uint64_t len)
51 4338ef2e 2024-05-18 benni {
52 4338ef2e 2024-05-18 benni uint8_t *p;
53 4338ef2e 2024-05-18 benni
54 4338ef2e 2024-05-18 benni for (uint64_t i = 0; i < len; i += sb.bsize) {
55 4338ef2e 2024-05-18 benni read_block (begin + i, buffer);
56 4338ef2e 2024-05-18 benni for (uint32_t j = 0; j < MIN (len, sb.bsize); ++j) {
57 4338ef2e 2024-05-18 benni p = buffer + j;
58 4338ef2e 2024-05-18 benni if (*p == 0)
59 4338ef2e 2024-05-18 benni continue;
60 4338ef2e 2024-05-18 benni
61 4338ef2e 2024-05-18 benni for (unsigned k = 0; k < 8; ++k) {
62 4338ef2e 2024-05-18 benni uint8_t mask = 1 << k;
63 4338ef2e 2024-05-18 benni if ((*p & mask) == mask) {
64 4338ef2e 2024-05-18 benni printf ("i=%zu, j=%u, k=%u\n", (size_t)i, j, k);
65 4338ef2e 2024-05-18 benni *p &= ~mask;
66 4338ef2e 2024-05-18 benni write_block (begin + i, buffer);
67 4338ef2e 2024-05-18 benni return (i + j) * 8 + k;
68 4338ef2e 2024-05-18 benni }
69 4338ef2e 2024-05-18 benni }
70 4338ef2e 2024-05-18 benni }
71 4338ef2e 2024-05-18 benni }
72 4338ef2e 2024-05-18 benni
73 4338ef2e 2024-05-18 benni return -1;
74 4338ef2e 2024-05-18 benni }
75 4338ef2e 2024-05-18 benni
76 4338ef2e 2024-05-18 benni static void free_bitmap (uint64_t begin, uint64_t idx)
77 4338ef2e 2024-05-18 benni {
78 4338ef2e 2024-05-18 benni uint64_t blkno;
79 4338ef2e 2024-05-18 benni unsigned off, bit;
80 4338ef2e 2024-05-18 benni
81 4338ef2e 2024-05-18 benni blkno = begin + idx / (8 * sb.bsize);
82 4338ef2e 2024-05-18 benni off = (idx / 8) % sb.bsize;
83 4338ef2e 2024-05-18 benni bit = idx % 8;
84 4338ef2e 2024-05-18 benni
85 4338ef2e 2024-05-18 benni printf ("free_bitmap(%zu, %zu, %zu, %u, %u);\n", (size_t)begin, (size_t)idx, (size_t)blkno, off, bit);
86 4338ef2e 2024-05-18 benni
87 4338ef2e 2024-05-18 benni read_block (blkno, buffer);
88 4338ef2e 2024-05-18 benni ((uint8_t *)buffer)[off] |= 1 << bit;
89 4338ef2e 2024-05-18 benni write_block (blkno, buffer);
90 4338ef2e 2024-05-18 benni }
91 4338ef2e 2024-05-18 benni
92 4338ef2e 2024-05-18 benni static uint64_t alloc_inode (void)
93 4338ef2e 2024-05-18 benni {
94 4338ef2e 2024-05-18 benni uint64_t ino = alloc_bitmap (sb.ibmoff, sb.nino);
95 4338ef2e 2024-05-18 benni
96 4338ef2e 2024-05-18 benni printf ("alloc_inode(): %zu\n", (size_t)ino);
97 4338ef2e 2024-05-18 benni
98 4338ef2e 2024-05-18 benni return ino;
99 4338ef2e 2024-05-18 benni }
100 4338ef2e 2024-05-18 benni
101 4338ef2e 2024-05-18 benni static void free_dblock (uint64_t blkno)
102 4338ef2e 2024-05-18 benni {
103 4338ef2e 2024-05-18 benni free_bitmap (sb.dbmoff, blkno - sb.doff);
104 4338ef2e 2024-05-18 benni }
105 4338ef2e 2024-05-18 benni
106 4338ef2e 2024-05-18 benni static void free_inode (uint64_t ino)
107 4338ef2e 2024-05-18 benni {
108 4338ef2e 2024-05-18 benni struct sufs_inode in;
109 4338ef2e 2024-05-18 benni
110 4338ef2e 2024-05-18 benni printf ("free_inode(%zu);\n", (size_t)ino);
111 4338ef2e 2024-05-18 benni
112 4338ef2e 2024-05-18 benni in = read_inode (ino);
113 4338ef2e 2024-05-18 benni
114 4338ef2e 2024-05-18 benni --in.nlink;
115 4338ef2e 2024-05-18 benni
116 4338ef2e 2024-05-18 benni if (in.nlink != 0) {
117 4338ef2e 2024-05-18 benni write_inode (ino, &in);
118 4338ef2e 2024-05-18 benni return;
119 4338ef2e 2024-05-18 benni }
120 4338ef2e 2024-05-18 benni
121 4338ef2e 2024-05-18 benni for (uint64_t i = 0; i < MIN (in.blocks, SUFS_NDIRECT); ++i) {
122 4338ef2e 2024-05-18 benni free_dblock (in.direct[i]);
123 4338ef2e 2024-05-18 benni }
124 4338ef2e 2024-05-18 benni
125 4338ef2e 2024-05-18 benni if (in.blocks >= SUFS_NDIRECT)
126 4338ef2e 2024-05-18 benni errx (1, "free_inode(): TODO: indirect blocks");
127 4338ef2e 2024-05-18 benni
128 4338ef2e 2024-05-18 benni free_bitmap (sb.ibmoff, ino);
129 4338ef2e 2024-05-18 benni }
130 4338ef2e 2024-05-18 benni
131 4338ef2e 2024-05-18 benni static uint64_t alloc_dblock (void)
132 4338ef2e 2024-05-18 benni {
133 4338ef2e 2024-05-18 benni uint64_t b = alloc_bitmap (sb.dbmoff, sb.ndata) + sb.doff;
134 4338ef2e 2024-05-18 benni memset (buffer, 0, sb.bsize);
135 4338ef2e 2024-05-18 benni write_block (b, buffer);
136 4338ef2e 2024-05-18 benni printf ("alloc_dblock(): %zu\n", (size_t)b);
137 4338ef2e 2024-05-18 benni return b;
138 4338ef2e 2024-05-18 benni }
139 4338ef2e 2024-05-18 benni
140 4338ef2e 2024-05-18 benni uint64_t resolve_inode_block (const struct sufs_inode *in, uint64_t blkno)
141 4338ef2e 2024-05-18 benni {
142 4338ef2e 2024-05-18 benni const size_t pbp = sb.bsize / sizeof (uint64_t);
143 4338ef2e 2024-05-18 benni volatile uint64_t *tmp = (volatile uint64_t *)buffer;
144 4338ef2e 2024-05-18 benni uint64_t i;
145 4338ef2e 2024-05-18 benni
146 4338ef2e 2024-05-18 benni if (blkno < SUFS_NDIRECT) {
147 4338ef2e 2024-05-18 benni return in->direct[blkno];
148 4338ef2e 2024-05-18 benni } else if (blkno < (SUFS_NDIRECT + pbp)) {
149 4338ef2e 2024-05-18 benni read_block (in->indir[0], buffer);
150 4338ef2e 2024-05-18 benni return tmp[blkno - SUFS_NDIRECT];
151 4338ef2e 2024-05-18 benni } else if (blkno < (SUFS_NDIRECT + pbp * pbp)) {
152 4338ef2e 2024-05-18 benni read_block (in->indir[1], buffer);
153 4338ef2e 2024-05-18 benni i = blkno - SUFS_NDIRECT - pbp;
154 4338ef2e 2024-05-18 benni read_block (tmp[i / pbp], buffer);
155 4338ef2e 2024-05-18 benni return tmp[i % pbp];
156 4338ef2e 2024-05-18 benni } else if (blkno < (SUFS_NDIRECT + pbp * pbp * pbp)) {
157 4338ef2e 2024-05-18 benni read_block (in->indir[2], buffer);
158 4338ef2e 2024-05-18 benni i = blkno - SUFS_NDIRECT - pbp * pbp;
159 4338ef2e 2024-05-18 benni read_block (tmp[i / pbp / pbp], buffer);
160 4338ef2e 2024-05-18 benni read_block (tmp[i / pbp % pbp], buffer);
161 4338ef2e 2024-05-18 benni return tmp[i % pbp];
162 4338ef2e 2024-05-18 benni } else {
163 4338ef2e 2024-05-18 benni errx (1, "resolve_inode_block(): inode out of range");
164 4338ef2e 2024-05-18 benni }
165 4338ef2e 2024-05-18 benni }
166 4338ef2e 2024-05-18 benni
167 4338ef2e 2024-05-18 benni void free_block (uint64_t block)
168 4338ef2e 2024-05-18 benni {
169 4338ef2e 2024-05-18 benni if (block == 0)
170 4338ef2e 2024-05-18 benni return;
171 4338ef2e 2024-05-18 benni
172 4338ef2e 2024-05-18 benni errx (1, "free_block(): TODO");
173 4338ef2e 2024-05-18 benni }
174 4338ef2e 2024-05-18 benni
175 4338ef2e 2024-05-18 benni void map_inode (uint64_t ino, struct sufs_inode *in, uint64_t blkno, uint64_t block)
176 4338ef2e 2024-05-18 benni {
177 4338ef2e 2024-05-18 benni const size_t pbp = sb.bsize / sizeof (uint64_t);
178 4338ef2e 2024-05-18 benni volatile uint64_t *tmp = (volatile uint64_t *)buffer;
179 4338ef2e 2024-05-18 benni uint64_t i;
180 4338ef2e 2024-05-18 benni
181 4338ef2e 2024-05-18 benni printf ("map_inode(%zu, %zu, %zu);\n", (size_t)ino, (size_t)blkno, (size_t)block);
182 4338ef2e 2024-05-18 benni
183 4338ef2e 2024-05-18 benni if (blkno < SUFS_NDIRECT) {
184 4338ef2e 2024-05-18 benni free_block (in->direct[blkno]);
185 4338ef2e 2024-05-18 benni in->direct[blkno] = block;
186 4338ef2e 2024-05-18 benni } else if (blkno < (SUFS_NDIRECT + pbp)) {
187 4338ef2e 2024-05-18 benni if (in->indir[0] == 0) {
188 4338ef2e 2024-05-18 benni in->indir[0] = alloc_dblock ();
189 4338ef2e 2024-05-18 benni write_inode (ino, in);
190 4338ef2e 2024-05-18 benni }
191 4338ef2e 2024-05-18 benni read_block (in->indir[0], buffer);
192 4338ef2e 2024-05-18 benni tmp[blkno - SUFS_NDIRECT] = block;
193 4338ef2e 2024-05-18 benni write_block (in->indir[0], buffer);
194 4338ef2e 2024-05-18 benni } else if (blkno < (SUFS_NDIRECT + pbp * pbp)) {
195 4338ef2e 2024-05-18 benni if (in->indir[1] == 0) {
196 4338ef2e 2024-05-18 benni in->indir[1] = alloc_dblock ();
197 4338ef2e 2024-05-18 benni write_inode (ino, in);
198 4338ef2e 2024-05-18 benni }
199 4338ef2e 2024-05-18 benni read_block (in->indir[1], buffer);
200 4338ef2e 2024-05-18 benni i = blkno - SUFS_NDIRECT - pbp;
201 4338ef2e 2024-05-18 benni if (tmp[i / pbp] == 0) {
202 4338ef2e 2024-05-18 benni tmp[i / pbp] = alloc_dblock ();
203 4338ef2e 2024-05-18 benni write_block (in->indir[1], buffer);
204 4338ef2e 2024-05-18 benni }
205 4338ef2e 2024-05-18 benni read_block (tmp[i / pbp], buffer);
206 4338ef2e 2024-05-18 benni tmp[i % pbp] = block;
207 4338ef2e 2024-05-18 benni write_block (tmp[i % pbp], buffer);
208 4338ef2e 2024-05-18 benni } else if (blkno < (SUFS_NDIRECT + pbp * pbp * pbp)) {
209 4338ef2e 2024-05-18 benni if (in->indir[2] == 0) {
210 4338ef2e 2024-05-18 benni in->indir[2] = alloc_dblock ();
211 4338ef2e 2024-05-18 benni write_inode (ino, in);
212 4338ef2e 2024-05-18 benni }
213 4338ef2e 2024-05-18 benni
214 4338ef2e 2024-05-18 benni read_block (in->indir[2], buffer);
215 4338ef2e 2024-05-18 benni i = blkno - SUFS_NDIRECT - pbp * pbp;
216 4338ef2e 2024-05-18 benni if (tmp[i / pbp / pbp] == 0) {
217 4338ef2e 2024-05-18 benni tmp[i / pbp / pbp] = alloc_dblock ();
218 4338ef2e 2024-05-18 benni write_block (in->indir[2], buffer);
219 4338ef2e 2024-05-18 benni }
220 4338ef2e 2024-05-18 benni
221 4338ef2e 2024-05-18 benni read_block (tmp[i / pbp / pbp], buffer);
222 4338ef2e 2024-05-18 benni
223 4338ef2e 2024-05-18 benni if (tmp[i / pbp % pbp] == 0) {
224 4338ef2e 2024-05-18 benni tmp[i / pbp % pbp] = alloc_dblock ();
225 4338ef2e 2024-05-18 benni write_block (tmp[i / pbp / pbp], buffer);
226 4338ef2e 2024-05-18 benni }
227 4338ef2e 2024-05-18 benni read_block (tmp[i / pbp % pbp], buffer);
228 4338ef2e 2024-05-18 benni tmp[i % pbp] = block;
229 4338ef2e 2024-05-18 benni write_block (tmp[i / pbp % pbp], buffer);
230 4338ef2e 2024-05-18 benni } else {
231 4338ef2e 2024-05-18 benni errx (1, "resolve_inode_block(): inode out of range");
232 4338ef2e 2024-05-18 benni }
233 4338ef2e 2024-05-18 benni }
234 4338ef2e 2024-05-18 benni
235 4338ef2e 2024-05-18 benni void read_block_inode (const struct sufs_inode *in, uint64_t blkno, char *buf)
236 4338ef2e 2024-05-18 benni {
237 4338ef2e 2024-05-18 benni uint64_t b;
238 4338ef2e 2024-05-18 benni
239 4338ef2e 2024-05-18 benni b = resolve_inode_block (in, blkno);
240 4338ef2e 2024-05-18 benni if (b != 0) {
241 4338ef2e 2024-05-18 benni read_block (b, buf);
242 4338ef2e 2024-05-18 benni } else {
243 4338ef2e 2024-05-18 benni memset (buf, 0, sb.bsize);
244 4338ef2e 2024-05-18 benni }
245 4338ef2e 2024-05-18 benni }
246 4338ef2e 2024-05-18 benni
247 4338ef2e 2024-05-18 benni void write_block_inode (uint64_t ino, struct sufs_inode *in, uint64_t blkno, const char *buf)
248 4338ef2e 2024-05-18 benni {
249 4338ef2e 2024-05-18 benni uint64_t b;
250 4338ef2e 2024-05-18 benni
251 4338ef2e 2024-05-18 benni b = resolve_inode_block (in, blkno);
252 4338ef2e 2024-05-18 benni if (b == 0) {
253 4338ef2e 2024-05-18 benni b = alloc_dblock ();
254 4338ef2e 2024-05-18 benni map_inode (ino, in, blkno, b);
255 4338ef2e 2024-05-18 benni ++in->blocks;
256 4338ef2e 2024-05-18 benni write_inode (ino, in);
257 4338ef2e 2024-05-18 benni }
258 4338ef2e 2024-05-18 benni write_block (b, buf);
259 4338ef2e 2024-05-18 benni }
260 4338ef2e 2024-05-18 benni
261 4338ef2e 2024-05-18 benni static struct sufs_inode read_inode (uint64_t ino)
262 4338ef2e 2024-05-18 benni {
263 4338ef2e 2024-05-18 benni struct sufs_inode in;
264 4338ef2e 2024-05-18 benni printf ("read_inode(%zu);\n", (size_t)ino);
265 4338ef2e 2024-05-18 benni read_block (sufs_iblk (sb, ino), buffer);
266 4338ef2e 2024-05-18 benni memcpy (&in, buffer + sufs_ioff (sb, ino), sizeof (in));
267 4338ef2e 2024-05-18 benni return in;
268 4338ef2e 2024-05-18 benni }
269 4338ef2e 2024-05-18 benni
270 4338ef2e 2024-05-18 benni static void write_inode (uint64_t ino, const struct sufs_inode *in)
271 4338ef2e 2024-05-18 benni {
272 4338ef2e 2024-05-18 benni printf ("write_inode(%zu);\n", (size_t)ino);
273 4338ef2e 2024-05-18 benni read_block (sufs_iblk (sb, ino), buffer);
274 4338ef2e 2024-05-18 benni memcpy (buffer + sufs_ioff (sb, ino), in, sizeof (*in));
275 4338ef2e 2024-05-18 benni write_block (sufs_iblk (sb, ino), buffer);
276 4338ef2e 2024-05-18 benni }
277 4338ef2e 2024-05-18 benni
278 4338ef2e 2024-05-18 benni static uint64_t searchdir (uint64_t ino, const char *name)
279 4338ef2e 2024-05-18 benni {
280 4338ef2e 2024-05-18 benni struct sufs_dirent *ent;
281 4338ef2e 2024-05-18 benni struct sufs_inode in;
282 4338ef2e 2024-05-18 benni uint64_t i;
283 4338ef2e 2024-05-18 benni size_t n, len;
284 4338ef2e 2024-05-18 benni
285 4338ef2e 2024-05-18 benni printf ("searchdir(%zu, %s);\n", (size_t)ino, name);
286 4338ef2e 2024-05-18 benni
287 4338ef2e 2024-05-18 benni len = strlen (name);
288 4338ef2e 2024-05-18 benni
289 4338ef2e 2024-05-18 benni in = read_inode (ino);
290 4338ef2e 2024-05-18 benni if ((in.mode & S_IFMT) != S_IFDIR) {
291 4338ef2e 2024-05-18 benni errno = ENOTDIR;
292 4338ef2e 2024-05-18 benni return 0;
293 4338ef2e 2024-05-18 benni }
294 4338ef2e 2024-05-18 benni
295 4338ef2e 2024-05-18 benni for (i = 0; i < in.blocks; ++i) {
296 4338ef2e 2024-05-18 benni read_block_inode (&in, i, buffer);
297 4338ef2e 2024-05-18 benni
298 4338ef2e 2024-05-18 benni for (n = 0; n < sb.bsize; n += ent->size) {
299 4338ef2e 2024-05-18 benni ent = (struct sufs_dirent *)(buffer + n);
300 4338ef2e 2024-05-18 benni
301 4338ef2e 2024-05-18 benni if (ent->ino == 0)
302 4338ef2e 2024-05-18 benni break;
303 4338ef2e 2024-05-18 benni
304 4338ef2e 2024-05-18 benni if (ent->len != len)
305 4338ef2e 2024-05-18 benni continue;
306 4338ef2e 2024-05-18 benni
307 4338ef2e 2024-05-18 benni if (memcmp (name, ent->name, len) == 0)
308 4338ef2e 2024-05-18 benni return ent->ino;
309 4338ef2e 2024-05-18 benni }
310 4338ef2e 2024-05-18 benni }
311 4338ef2e 2024-05-18 benni
312 4338ef2e 2024-05-18 benni errno = ENOENT;
313 4338ef2e 2024-05-18 benni return 0;
314 4338ef2e 2024-05-18 benni }
315 4338ef2e 2024-05-18 benni
316 4338ef2e 2024-05-18 benni static uint64_t lookup2 (char *path)
317 4338ef2e 2024-05-18 benni {
318 4338ef2e 2024-05-18 benni uint64_t parent;
319 4338ef2e 2024-05-18 benni char *name, *slash;
320 4338ef2e 2024-05-18 benni size_t len;
321 4338ef2e 2024-05-18 benni
322 4338ef2e 2024-05-18 benni // remove trailing slashes
323 4338ef2e 2024-05-18 benni len = strlen (path);
324 4338ef2e 2024-05-18 benni while (len > 0 && path[len - 1] == '/')
325 4338ef2e 2024-05-18 benni --len;
326 4338ef2e 2024-05-18 benni path[len] = '\0';
327 4338ef2e 2024-05-18 benni
328 4338ef2e 2024-05-18 benni if (len == 0 || strcmp (path, "/") == 0)
329 4338ef2e 2024-05-18 benni return SUFS_INO_ROOT;
330 4338ef2e 2024-05-18 benni
331 4338ef2e 2024-05-18 benni // split path at '/'
332 4338ef2e 2024-05-18 benni slash = strrchr (path, '/');
333 4338ef2e 2024-05-18 benni if (slash == NULL)
334 4338ef2e 2024-05-18 benni errx (1, "lookup2(): failed to split path");
335 4338ef2e 2024-05-18 benni *slash = '\0';
336 4338ef2e 2024-05-18 benni name = slash + 1;
337 4338ef2e 2024-05-18 benni
338 4338ef2e 2024-05-18 benni // find parent inode
339 4338ef2e 2024-05-18 benni parent = lookup2 (path);
340 4338ef2e 2024-05-18 benni if (parent == 0) {
341 4338ef2e 2024-05-18 benni return 0;
342 4338ef2e 2024-05-18 benni }
343 4338ef2e 2024-05-18 benni
344 4338ef2e 2024-05-18 benni return searchdir (parent, name);
345 4338ef2e 2024-05-18 benni }
346 4338ef2e 2024-05-18 benni
347 4338ef2e 2024-05-18 benni static uint64_t lookup (const char *path)
348 4338ef2e 2024-05-18 benni {
349 4338ef2e 2024-05-18 benni uint64_t ino;
350 4338ef2e 2024-05-18 benni char *buf;
351 4338ef2e 2024-05-18 benni
352 4338ef2e 2024-05-18 benni printf ("lookup(\"%s\");\n", path);
353 4338ef2e 2024-05-18 benni
354 4338ef2e 2024-05-18 benni if (*path != '/') {
355 4338ef2e 2024-05-18 benni errno = EINVAL;
356 4338ef2e 2024-05-18 benni return 0;
357 4338ef2e 2024-05-18 benni }
358 4338ef2e 2024-05-18 benni
359 4338ef2e 2024-05-18 benni buf = strdup (path);
360 4338ef2e 2024-05-18 benni ino = lookup2 (buf);
361 4338ef2e 2024-05-18 benni
362 4338ef2e 2024-05-18 benni free (buf);
363 4338ef2e 2024-05-18 benni return ino;
364 4338ef2e 2024-05-18 benni }
365 4338ef2e 2024-05-18 benni
366 4338ef2e 2024-05-18 benni int sufs_getattr (const char *path, struct stat *st)
367 4338ef2e 2024-05-18 benni {
368 4338ef2e 2024-05-18 benni struct sufs_inode in;
369 4338ef2e 2024-05-18 benni uint64_t ino;
370 4338ef2e 2024-05-18 benni
371 4338ef2e 2024-05-18 benni printf ("getattr(\"%s\");\n", path);
372 4338ef2e 2024-05-18 benni
373 4338ef2e 2024-05-18 benni ino = lookup (path);
374 4338ef2e 2024-05-18 benni if (ino == 0)
375 4338ef2e 2024-05-18 benni return -errno;
376 4338ef2e 2024-05-18 benni
377 4338ef2e 2024-05-18 benni in = read_inode (ino);
378 4338ef2e 2024-05-18 benni
379 4338ef2e 2024-05-18 benni st->st_ino = ino;
380 4338ef2e 2024-05-18 benni st->st_mode = in.mode;
381 4338ef2e 2024-05-18 benni printf ("mode = %o\n", (unsigned)in.mode);
382 4338ef2e 2024-05-18 benni st->st_nlink = in.nlink;
383 4338ef2e 2024-05-18 benni st->st_uid = in.uid;
384 4338ef2e 2024-05-18 benni st->st_gid = in.gid;
385 4338ef2e 2024-05-18 benni st->st_atime = in.atime;
386 4338ef2e 2024-05-18 benni st->st_mtime = in.mtime;
387 4338ef2e 2024-05-18 benni st->st_ctime = in.ctime;
388 4338ef2e 2024-05-18 benni st->st_size = in.size;
389 4338ef2e 2024-05-18 benni st->st_blocks = in.blocks;
390 4338ef2e 2024-05-18 benni st->st_blksize = sb.bsize;
391 4338ef2e 2024-05-18 benni return 0;
392 4338ef2e 2024-05-18 benni }
393 4338ef2e 2024-05-18 benni
394 4338ef2e 2024-05-18 benni int sufs_open (const char *path, struct fuse_file_info *ffi)
395 4338ef2e 2024-05-18 benni {
396 4338ef2e 2024-05-18 benni uint64_t ino;
397 4338ef2e 2024-05-18 benni
398 4338ef2e 2024-05-18 benni ino = lookup (path);
399 4338ef2e 2024-05-18 benni return ino > 0 ? 0 : -errno;
400 4338ef2e 2024-05-18 benni }
401 4338ef2e 2024-05-18 benni
402 4338ef2e 2024-05-18 benni int sufs_read (const char *path, char *buf, size_t size, off_t off, struct fuse_file_info *ffi)
403 4338ef2e 2024-05-18 benni {
404 4338ef2e 2024-05-18 benni struct sufs_inode in;
405 4338ef2e 2024-05-18 benni uint64_t ino;
406 4338ef2e 2024-05-18 benni
407 4338ef2e 2024-05-18 benni printf ("read(\"%s\", %zu, %zu);\n", path, (size_t)off, size);
408 4338ef2e 2024-05-18 benni
409 4338ef2e 2024-05-18 benni ino = lookup (path);
410 4338ef2e 2024-05-18 benni if (ino == 0)
411 4338ef2e 2024-05-18 benni return -errno;
412 4338ef2e 2024-05-18 benni
413 4338ef2e 2024-05-18 benni in = read_inode (ino);
414 4338ef2e 2024-05-18 benni
415 4338ef2e 2024-05-18 benni if (off > in.size)
416 4338ef2e 2024-05-18 benni return 0;
417 4338ef2e 2024-05-18 benni
418 4338ef2e 2024-05-18 benni if ((off + size) >= sb.bsize)
419 4338ef2e 2024-05-18 benni size = sb.bsize - off;
420 4338ef2e 2024-05-18 benni
421 4338ef2e 2024-05-18 benni if ((off + size) >= in.size)
422 4338ef2e 2024-05-18 benni size = in.size - off;
423 4338ef2e 2024-05-18 benni
424 4338ef2e 2024-05-18 benni read_block_inode (&in, off / sb.bsize, dbuffer);
425 4338ef2e 2024-05-18 benni memcpy (buf, dbuffer + off % sb.bsize, size);
426 4338ef2e 2024-05-18 benni
427 4338ef2e 2024-05-18 benni return size;
428 4338ef2e 2024-05-18 benni }
429 4338ef2e 2024-05-18 benni
430 4338ef2e 2024-05-18 benni int sufs_write (const char *path, const char *buf, size_t size, off_t off, struct fuse_file_info *ffi)
431 4338ef2e 2024-05-18 benni {
432 4338ef2e 2024-05-18 benni struct sufs_inode in;
433 4338ef2e 2024-05-18 benni uint64_t ino;
434 4338ef2e 2024-05-18 benni
435 4338ef2e 2024-05-18 benni printf ("write(\"%s\", %zu, %zu);\n", path, size, (size_t)off);
436 4338ef2e 2024-05-18 benni
437 4338ef2e 2024-05-18 benni ino = lookup (path);
438 4338ef2e 2024-05-18 benni if (ino == 0)
439 4338ef2e 2024-05-18 benni return -errno;
440 4338ef2e 2024-05-18 benni
441 4338ef2e 2024-05-18 benni in = read_inode (ino);
442 4338ef2e 2024-05-18 benni
443 4338ef2e 2024-05-18 benni if ((off + size) >= sb.bsize)
444 4338ef2e 2024-05-18 benni size = sb.bsize - off;
445 4338ef2e 2024-05-18 benni
446 4338ef2e 2024-05-18 benni memcpy (dbuffer + off % sb.bsize, buf, size);
447 4338ef2e 2024-05-18 benni write_block_inode (ino, &in, off / sb.bsize, dbuffer);
448 4338ef2e 2024-05-18 benni
449 4338ef2e 2024-05-18 benni if (off + size >= in.size)
450 4338ef2e 2024-05-18 benni in.size = off + size;
451 4338ef2e 2024-05-18 benni
452 4338ef2e 2024-05-18 benni write_inode (ino, &in);
453 4338ef2e 2024-05-18 benni
454 4338ef2e 2024-05-18 benni return size;
455 4338ef2e 2024-05-18 benni }
456 4338ef2e 2024-05-18 benni
457 4338ef2e 2024-05-18 benni int sufs_readdir (const char *path, void *data, fuse_fill_dir_t filler, off_t off, struct fuse_file_info *ffi)
458 4338ef2e 2024-05-18 benni {
459 4338ef2e 2024-05-18 benni char name[256];
460 4338ef2e 2024-05-18 benni struct sufs_dirent *ent;
461 4338ef2e 2024-05-18 benni struct sufs_inode in;
462 4338ef2e 2024-05-18 benni uint64_t ino;
463 4338ef2e 2024-05-18 benni size_t len;
464 4338ef2e 2024-05-18 benni
465 4338ef2e 2024-05-18 benni if (off != 0)
466 4338ef2e 2024-05-18 benni return 0;
467 4338ef2e 2024-05-18 benni
468 4338ef2e 2024-05-18 benni ino = lookup (path);
469 4338ef2e 2024-05-18 benni if (ino == 0)
470 4338ef2e 2024-05-18 benni return -errno;
471 4338ef2e 2024-05-18 benni
472 4338ef2e 2024-05-18 benni in = read_inode (ino);
473 4338ef2e 2024-05-18 benni
474 4338ef2e 2024-05-18 benni for (uint64_t i = 0; i < in.blocks; ++i) {
475 4338ef2e 2024-05-18 benni read_block_inode (&in, i, buffer);
476 4338ef2e 2024-05-18 benni for (uint32_t j = 0; j < sb.bsize; j += ent->size) {
477 4338ef2e 2024-05-18 benni ent = (struct sufs_dirent *)(buffer + j);
478 4338ef2e 2024-05-18 benni if (ent->size == 0)
479 4338ef2e 2024-05-18 benni break;
480 4338ef2e 2024-05-18 benni len = ent->len;
481 4338ef2e 2024-05-18 benni memcpy (name, ent->name, len);
482 4338ef2e 2024-05-18 benni name[len] = '\0';
483 4338ef2e 2024-05-18 benni filler (data, name, NULL, 0);
484 4338ef2e 2024-05-18 benni }
485 4338ef2e 2024-05-18 benni }
486 4338ef2e 2024-05-18 benni
487 4338ef2e 2024-05-18 benni
488 4338ef2e 2024-05-18 benni return 0;
489 4338ef2e 2024-05-18 benni }
490 4338ef2e 2024-05-18 benni
491 4338ef2e 2024-05-18 benni int sufs_chown (const char *path, uid_t uid, gid_t gid)
492 4338ef2e 2024-05-18 benni {
493 4338ef2e 2024-05-18 benni struct sufs_inode in;
494 4338ef2e 2024-05-18 benni uint64_t ino;
495 4338ef2e 2024-05-18 benni
496 4338ef2e 2024-05-18 benni printf ("chown(\"%s\", %u, %u);\n", path, (unsigned)uid, (unsigned)gid);
497 4338ef2e 2024-05-18 benni
498 4338ef2e 2024-05-18 benni ino = lookup (path);
499 4338ef2e 2024-05-18 benni if (ino == 0)
500 4338ef2e 2024-05-18 benni return -errno;
501 4338ef2e 2024-05-18 benni
502 4338ef2e 2024-05-18 benni in = read_inode (ino);
503 4338ef2e 2024-05-18 benni
504 4338ef2e 2024-05-18 benni if (uid != -1)
505 4338ef2e 2024-05-18 benni in.uid = uid;
506 4338ef2e 2024-05-18 benni
507 4338ef2e 2024-05-18 benni if (gid != -1)
508 4338ef2e 2024-05-18 benni in.gid = gid;
509 4338ef2e 2024-05-18 benni
510 4338ef2e 2024-05-18 benni write_inode (ino, &in);
511 4338ef2e 2024-05-18 benni
512 4338ef2e 2024-05-18 benni return 0;
513 4338ef2e 2024-05-18 benni }
514 4338ef2e 2024-05-18 benni
515 4338ef2e 2024-05-18 benni int sufs_chmod (const char *path, mode_t mode)
516 4338ef2e 2024-05-18 benni {
517 4338ef2e 2024-05-18 benni struct sufs_inode in;
518 4338ef2e 2024-05-18 benni uint64_t ino;
519 4338ef2e 2024-05-18 benni
520 4338ef2e 2024-05-18 benni ino = lookup (path);
521 4338ef2e 2024-05-18 benni if (ino == 0)
522 4338ef2e 2024-05-18 benni return -errno;
523 4338ef2e 2024-05-18 benni
524 4338ef2e 2024-05-18 benni in = read_inode (ino);
525 4338ef2e 2024-05-18 benni
526 4338ef2e 2024-05-18 benni in.mode &= ~07777;
527 4338ef2e 2024-05-18 benni in.mode |= mode & 07777;
528 4338ef2e 2024-05-18 benni
529 4338ef2e 2024-05-18 benni write_inode (ino, &in);
530 4338ef2e 2024-05-18 benni
531 4338ef2e 2024-05-18 benni return 0;
532 4338ef2e 2024-05-18 benni }
533 4338ef2e 2024-05-18 benni
534 4338ef2e 2024-05-18 benni
535 4338ef2e 2024-05-18 benni static int add_to_dir (uint64_t pino, struct sufs_inode *pin, const char *name, uint64_t ino)
536 4338ef2e 2024-05-18 benni {
537 4338ef2e 2024-05-18 benni struct sufs_dirent *ent, *new;
538 4338ef2e 2024-05-18 benni uint16_t rem;
539 4338ef2e 2024-05-18 benni uint64_t i, off;
540 4338ef2e 2024-05-18 benni size_t len;
541 4338ef2e 2024-05-18 benni
542 4338ef2e 2024-05-18 benni printf ("add_to_dir(\"%s\", %zu);\n", name, (size_t)ino);
543 4338ef2e 2024-05-18 benni
544 4338ef2e 2024-05-18 benni len = strlen (name);
545 4338ef2e 2024-05-18 benni if (len > 255) {
546 4338ef2e 2024-05-18 benni errno = -E2BIG;
547 4338ef2e 2024-05-18 benni return -1;
548 4338ef2e 2024-05-18 benni }
549 4338ef2e 2024-05-18 benni
550 4338ef2e 2024-05-18 benni for (i = 0; i < pin->blocks; ++i) {
551 4338ef2e 2024-05-18 benni read_block_inode (pin, i, buffer);
552 4338ef2e 2024-05-18 benni for (uint64_t j = 0; j < sb.bsize; j += ent->size) {
553 4338ef2e 2024-05-18 benni ent = (struct sufs_dirent *)(buffer + j);
554 4338ef2e 2024-05-18 benni if (ent->size == 0)
555 4338ef2e 2024-05-18 benni break;
556 4338ef2e 2024-05-18 benni
557 4338ef2e 2024-05-18 benni printf ("ent = { ino: %zu, len: %zu, size: %zu, name: \"%*s\" }\n",
558 4338ef2e 2024-05-18 benni (size_t)ent->ino, (size_t)ent->len, (size_t)ent->size, (int)ent->len, ent->name);
559 4338ef2e 2024-05-18 benni
560 4338ef2e 2024-05-18 benni rem = ent->size - ent->len - sizeof (struct sufs_dirent);
561 4338ef2e 2024-05-18 benni
562 4338ef2e 2024-05-18 benni printf ("rem = %zu\n", (size_t)rem);
563 4338ef2e 2024-05-18 benni
564 4338ef2e 2024-05-18 benni if (rem < (sizeof (struct sufs_dirent) + len + 8))
565 4338ef2e 2024-05-18 benni continue;
566 4338ef2e 2024-05-18 benni
567 4338ef2e 2024-05-18 benni off = j + sizeof (struct sufs_dirent) + len;
568 4338ef2e 2024-05-18 benni off = (off + 7) & ~7;
569 4338ef2e 2024-05-18 benni printf ("j = %zu, off = %zu\n", (size_t)j, (size_t)off);
570 4338ef2e 2024-05-18 benni
571 4338ef2e 2024-05-18 benni new = (struct sufs_dirent *)(buffer + off);
572 4338ef2e 2024-05-18 benni new->ino = ino;
573 4338ef2e 2024-05-18 benni new->size = rem;
574 4338ef2e 2024-05-18 benni new->len = len;
575 4338ef2e 2024-05-18 benni memcpy (new->name, name, len);
576 4338ef2e 2024-05-18 benni ent->size = off - j;
577 4338ef2e 2024-05-18 benni
578 4338ef2e 2024-05-18 benni write_block_inode (pino, pin, i, buffer);
579 4338ef2e 2024-05-18 benni return 0;
580 4338ef2e 2024-05-18 benni }
581 4338ef2e 2024-05-18 benni }
582 4338ef2e 2024-05-18 benni
583 4338ef2e 2024-05-18 benni errx (1, "add_to_dir(): TODO: allocating new directory blocks");
584 4338ef2e 2024-05-18 benni }
585 4338ef2e 2024-05-18 benni
586 4338ef2e 2024-05-18 benni static int find_parent (const char *path, struct sufs_inode *parent)
587 4338ef2e 2024-05-18 benni {
588 4338ef2e 2024-05-18 benni uint64_t ino;
589 4338ef2e 2024-05-18 benni char *ppath, *tmp;
590 4338ef2e 2024-05-18 benni
591 4338ef2e 2024-05-18 benni tmp = strdup (path);
592 4338ef2e 2024-05-18 benni ppath = dirname (tmp);
593 4338ef2e 2024-05-18 benni ino = lookup (ppath);
594 4338ef2e 2024-05-18 benni free (tmp);
595 4338ef2e 2024-05-18 benni if (ino == 0)
596 4338ef2e 2024-05-18 benni return -1;
597 4338ef2e 2024-05-18 benni
598 4338ef2e 2024-05-18 benni *parent = read_inode (ino);
599 4338ef2e 2024-05-18 benni return (parent->mode & S_IFMT) == S_IFDIR ? 0 : -1;
600 4338ef2e 2024-05-18 benni }
601 4338ef2e 2024-05-18 benni
602 4338ef2e 2024-05-18 benni int sufs_mknod (const char *path, mode_t mode, dev_t dev)
603 4338ef2e 2024-05-18 benni {
604 4338ef2e 2024-05-18 benni struct fuse_context *ctx;
605 4338ef2e 2024-05-18 benni struct sufs_inode pin, in;
606 4338ef2e 2024-05-18 benni uint64_t pino, ino;
607 4338ef2e 2024-05-18 benni char *name, *ppath, *tmp;
608 4338ef2e 2024-05-18 benni
609 4338ef2e 2024-05-18 benni printf ("mknod(\"%s\", %o, %u);\n", path, (unsigned)mode, (unsigned)dev);
610 4338ef2e 2024-05-18 benni
611 4338ef2e 2024-05-18 benni tmp = strdup (path);
612 4338ef2e 2024-05-18 benni ppath = dirname (tmp);
613 4338ef2e 2024-05-18 benni pino = lookup (ppath);
614 4338ef2e 2024-05-18 benni if (pino == 0)
615 4338ef2e 2024-05-18 benni return -errno;
616 4338ef2e 2024-05-18 benni
617 4338ef2e 2024-05-18 benni pin = read_inode (pino);
618 4338ef2e 2024-05-18 benni if ((pin.mode & S_IFMT) != S_IFDIR)
619 4338ef2e 2024-05-18 benni return -ENOTDIR;
620 4338ef2e 2024-05-18 benni
621 4338ef2e 2024-05-18 benni ino = alloc_inode ();
622 4338ef2e 2024-05-18 benni
623 4338ef2e 2024-05-18 benni ctx = fuse_get_context ();
624 4338ef2e 2024-05-18 benni memset (&in, 0, sizeof (in));
625 4338ef2e 2024-05-18 benni in.mode = mode;
626 4338ef2e 2024-05-18 benni in.nlink = 1;
627 4338ef2e 2024-05-18 benni in.uid = ctx->uid;
628 4338ef2e 2024-05-18 benni in.gid = pin.gid;
629 4338ef2e 2024-05-18 benni in.atime = time (NULL);
630 4338ef2e 2024-05-18 benni in.mtime = time (NULL);
631 4338ef2e 2024-05-18 benni in.ctime = time (NULL);
632 4338ef2e 2024-05-18 benni
633 4338ef2e 2024-05-18 benni write_inode (ino, &in);
634 4338ef2e 2024-05-18 benni
635 4338ef2e 2024-05-18 benni tmp = strdup (path);
636 4338ef2e 2024-05-18 benni name = basename (tmp);
637 4338ef2e 2024-05-18 benni add_to_dir (pino, &pin, name, ino);
638 4338ef2e 2024-05-18 benni return 0;
639 4338ef2e 2024-05-18 benni }
640 4338ef2e 2024-05-18 benni
641 4338ef2e 2024-05-18 benni int sufs_create (const char *path, mode_t mode, struct fuse_file_info *ffi)
642 4338ef2e 2024-05-18 benni {
643 4338ef2e 2024-05-18 benni return sufs_mknod (path, mode, 0);
644 4338ef2e 2024-05-18 benni }
645 4338ef2e 2024-05-18 benni
646 4338ef2e 2024-05-18 benni int sufs_release (const char *path, struct fuse_file_info *ffi)
647 4338ef2e 2024-05-18 benni {
648 4338ef2e 2024-05-18 benni return 0;
649 4338ef2e 2024-05-18 benni }
650 4338ef2e 2024-05-18 benni
651 4338ef2e 2024-05-18 benni int sufs_unlink (const char *path)
652 4338ef2e 2024-05-18 benni {
653 4338ef2e 2024-05-18 benni struct sufs_inode parent, in;
654 4338ef2e 2024-05-18 benni const char *name;
655 4338ef2e 2024-05-18 benni size_t len;
656 4338ef2e 2024-05-18 benni char *tmp;
657 4338ef2e 2024-05-18 benni
658 4338ef2e 2024-05-18 benni printf ("unlink(\"%s\");\n", path);
659 4338ef2e 2024-05-18 benni
660 4338ef2e 2024-05-18 benni if (find_parent (path, &parent) != 0)
661 4338ef2e 2024-05-18 benni return -errno;
662 4338ef2e 2024-05-18 benni
663 4338ef2e 2024-05-18 benni tmp = strdup (path);
664 4338ef2e 2024-05-18 benni name = basename (tmp);
665 4338ef2e 2024-05-18 benni len = strlen (name);
666 4338ef2e 2024-05-18 benni
667 4338ef2e 2024-05-18 benni for (uint64_t i = 0; i < parent.blocks; ++i) {
668 4338ef2e 2024-05-18 benni struct sufs_dirent *ent, *prent;
669 4338ef2e 2024-05-18 benni uint64_t blkno, ino;
670 4338ef2e 2024-05-18 benni uint32_t prev;
671 4338ef2e 2024-05-18 benni
672 4338ef2e 2024-05-18 benni blkno = resolve_inode_block (&parent, i);
673 4338ef2e 2024-05-18 benni if (blkno == 0)
674 4338ef2e 2024-05-18 benni continue;
675 4338ef2e 2024-05-18 benni read_block (blkno, buffer);
676 4338ef2e 2024-05-18 benni
677 4338ef2e 2024-05-18 benni for (uint32_t j = 0, prev = -1; j < sb.bsize; prev = j, j += ent->size) {
678 4338ef2e 2024-05-18 benni ent = (struct sufs_dirent *)(buffer + j);
679 4338ef2e 2024-05-18 benni ino = ent->ino;
680 4338ef2e 2024-05-18 benni
681 4338ef2e 2024-05-18 benni if (ino == 0 || len != ent->len)
682 4338ef2e 2024-05-18 benni continue;
683 4338ef2e 2024-05-18 benni
684 4338ef2e 2024-05-18 benni if (memcmp (name, ent->name, len) != 0)
685 4338ef2e 2024-05-18 benni continue;
686 4338ef2e 2024-05-18 benni
687 4338ef2e 2024-05-18 benni if (prev != -1) {
688 4338ef2e 2024-05-18 benni prent = (struct sufs_dirent *)(buffer + prev);
689 4338ef2e 2024-05-18 benni prent->size += ent->size;
690 4338ef2e 2024-05-18 benni } else if (ent->size == sb.bsize) {
691 4338ef2e 2024-05-18 benni ent->ino = 0;
692 4338ef2e 2024-05-18 benni } else {
693 4338ef2e 2024-05-18 benni errx (1, "sufs_unlink(): TODO: removing the first dirent in a block");
694 4338ef2e 2024-05-18 benni }
695 4338ef2e 2024-05-18 benni
696 4338ef2e 2024-05-18 benni write_block (blkno, buffer);
697 4338ef2e 2024-05-18 benni free_inode (ent->ino);
698 4338ef2e 2024-05-18 benni free (tmp);
699 4338ef2e 2024-05-18 benni return 0;
700 4338ef2e 2024-05-18 benni }
701 4338ef2e 2024-05-18 benni
702 4338ef2e 2024-05-18 benni }
703 4338ef2e 2024-05-18 benni
704 4338ef2e 2024-05-18 benni free (tmp);
705 4338ef2e 2024-05-18 benni return -ENOENT;
706 4338ef2e 2024-05-18 benni }
707 4338ef2e 2024-05-18 benni
708 4338ef2e 2024-05-18 benni int sufs_utime (const char *path, struct utimbuf *t)
709 4338ef2e 2024-05-18 benni {
710 4338ef2e 2024-05-18 benni struct sufs_inode in;
711 4338ef2e 2024-05-18 benni uint64_t ino;
712 4338ef2e 2024-05-18 benni
713 4338ef2e 2024-05-18 benni ino = lookup (path);
714 4338ef2e 2024-05-18 benni if (ino == 0)
715 4338ef2e 2024-05-18 benni return -errno;
716 4338ef2e 2024-05-18 benni
717 4338ef2e 2024-05-18 benni in = read_inode (ino);
718 4338ef2e 2024-05-18 benni in.atime = t->actime;
719 4338ef2e 2024-05-18 benni in.mtime = t->modtime;
720 4338ef2e 2024-05-18 benni write_inode (ino, &in);
721 4338ef2e 2024-05-18 benni return 0;
722 4338ef2e 2024-05-18 benni }
723 4338ef2e 2024-05-18 benni
724 4338ef2e 2024-05-18 benni struct fuse_operations fsops = {
725 4338ef2e 2024-05-18 benni .getattr = sufs_getattr,
726 4338ef2e 2024-05-18 benni .open = sufs_open,
727 4338ef2e 2024-05-18 benni .read = sufs_read,
728 4338ef2e 2024-05-18 benni .write = sufs_write,
729 4338ef2e 2024-05-18 benni .readdir = sufs_readdir,
730 4338ef2e 2024-05-18 benni .chown = sufs_chown,
731 4338ef2e 2024-05-18 benni .chmod = sufs_chmod,
732 4338ef2e 2024-05-18 benni .mknod = sufs_mknod,
733 4338ef2e 2024-05-18 benni .create = sufs_create,
734 4338ef2e 2024-05-18 benni .release = sufs_release,
735 4338ef2e 2024-05-18 benni .unlink = sufs_unlink,
736 4338ef2e 2024-05-18 benni .utime = sufs_utime,
737 4338ef2e 2024-05-18 benni };
738 4338ef2e 2024-05-18 benni
739 4338ef2e 2024-05-18 benni int opt_parse (void *data, const char *arg, int key, struct fuse_args *outargs)
740 4338ef2e 2024-05-18 benni {
741 4338ef2e 2024-05-18 benni switch (key) {
742 4338ef2e 2024-05-18 benni case KEY_VERSION:
743 4338ef2e 2024-05-18 benni fputs ("fuse_sufs v0\n", stderr);
744 4338ef2e 2024-05-18 benni fuse_opt_add_arg (outargs, "--version");
745 4338ef2e 2024-05-18 benni fuse_main (outargs->argc, outargs->argv, &fsops, NULL);
746 4338ef2e 2024-05-18 benni exit (0);
747 4338ef2e 2024-05-18 benni break;
748 4338ef2e 2024-05-18 benni case KEY_HELP:
749 4338ef2e 2024-05-18 benni fputs ("usage: fuse_sufs file mountpoint\n", stderr);
750 4338ef2e 2024-05-18 benni fuse_opt_add_arg (outargs, "-h");
751 4338ef2e 2024-05-18 benni fuse_main (outargs->argc, outargs->argv, &fsops, NULL);
752 4338ef2e 2024-05-18 benni exit (1);
753 4338ef2e 2024-05-18 benni break;
754 4338ef2e 2024-05-18 benni }
755 4338ef2e 2024-05-18 benni return 1;
756 4338ef2e 2024-05-18 benni }
757 4338ef2e 2024-05-18 benni
758 4338ef2e 2024-05-18 benni int main (int argc, char *argv[])
759 4338ef2e 2024-05-18 benni {
760 4338ef2e 2024-05-18 benni struct fuse_args args = FUSE_ARGS_INIT (argc, argv);
761 4338ef2e 2024-05-18 benni fuse_opt_parse (&args, NULL, opts, opt_parse);
762 4338ef2e 2024-05-18 benni
763 4338ef2e 2024-05-18 benni fd = open ("test.img", O_RDWR);
764 4338ef2e 2024-05-18 benni
765 4338ef2e 2024-05-18 benni if (fd < 0)
766 4338ef2e 2024-05-18 benni err (1, "open()");
767 4338ef2e 2024-05-18 benni
768 4338ef2e 2024-05-18 benni read (fd, &sb, sizeof (sb));
769 4338ef2e 2024-05-18 benni
770 4338ef2e 2024-05-18 benni if (sb.magic != SUFS_MAGIC) {
771 4338ef2e 2024-05-18 benni lseek (fd, SUFS_BOOTSIZE, SEEK_SET);
772 4338ef2e 2024-05-18 benni read (fd, &sb, sizeof (sb));
773 4338ef2e 2024-05-18 benni
774 4338ef2e 2024-05-18 benni if (sb.magic != SUFS_MAGIC)
775 4338ef2e 2024-05-18 benni errx (1, "invalid magic");
776 4338ef2e 2024-05-18 benni }
777 4338ef2e 2024-05-18 benni
778 4338ef2e 2024-05-18 benni buffer = malloc (sb.bsize);
779 4338ef2e 2024-05-18 benni dbuffer = malloc (sb.bsize);
780 4338ef2e 2024-05-18 benni
781 4338ef2e 2024-05-18 benni return fuse_main (argc, argv, &fsops, NULL);
782 4338ef2e 2024-05-18 benni }