This source file includes following definitions.
- fat_read_dirent
- fat_write_dirent
- fat_lookup_dirent
- fatfs_lookup_node
- fat_get_dirent
- fatfs_get_node
- fat_add_dirent
- fatfs_add_node
- fatfs_put_node
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <sys/prex.h>
31 #include <sys/buf.h>
32
33 #include <ctype.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <errno.h>
37 #include <stdlib.h>
38
39 #include "fatfs.h"
40
41
42
43
44 static int
45 fat_read_dirent(struct fatfsmount *fmp, u_long sec)
46 {
47 struct buf *bp;
48 int error;
49
50 if ((error = bread(fmp->dev, sec, &bp)) != 0)
51 return error;
52 memcpy(fmp->dir_buf, bp->b_data, SEC_SIZE);
53 brelse(bp);
54 return 0;
55 }
56
57
58
59
60 static int
61 fat_write_dirent(struct fatfsmount *fmp, u_long sec)
62 {
63 struct buf *bp;
64
65 bp = getblk(fmp->dev, sec);
66 memcpy(bp->b_data, fmp->dir_buf, SEC_SIZE);
67 return bwrite(bp);
68 }
69
70
71
72
73
74
75
76
77
78
79 static int
80 fat_lookup_dirent(struct fatfsmount *fmp, u_long sec, char *name,
81 struct fatfs_node *np)
82 {
83 struct fat_dirent *de;
84 int error, i;
85
86 error = fat_read_dirent(fmp, sec);
87 if (error)
88 return error;
89
90 de = (struct fat_dirent *)fmp->dir_buf;
91
92 for (i = 0; i < DIR_PER_SEC; i++) {
93
94 if (IS_EMPTY(de))
95 return ENOENT;
96 if (!IS_VOL(de) &&
97 !fat_compare_name((char *)de->name, name)) {
98
99 *(&np->dirent) = *de;
100 np->sector = sec;
101 np->offset = sizeof(struct fat_dirent) * i;
102 DPRINTF(("fat_lookup_dirent: found sec=%d\n", sec));
103 return 0;
104 }
105 if (!IS_DELETED(de))
106 DPRINTF(("fat_lookup_dirent: %s\n", de->name));
107 de++;
108 }
109 return EAGAIN;
110 }
111
112
113
114
115
116
117
118
119
120 int
121 fatfs_lookup_node(vnode_t dvp, char *name, struct fatfs_node *np)
122 {
123 struct fatfsmount *fmp;
124 char fat_name[12];
125 u_long cl, sec;
126 int i, error;
127
128 if (name == NULL)
129 return ENOENT;
130
131 DPRINTF(("fat_lookup_denode: cl=%d name=%s\n", dvp->v_blkno, name));
132
133 fat_convert_name(name, fat_name);
134 *(fat_name + 11) = '\0';
135
136 fmp = (struct fatfsmount *)dvp->v_mount->m_data;
137 cl = dvp->v_blkno;
138 if (cl == CL_ROOT) {
139
140 for (sec = fmp->root_start; sec < fmp->data_start; sec++) {
141 error = fat_lookup_dirent(fmp, sec, fat_name, np);
142 if (error != EAGAIN)
143 return error;
144 }
145 } else {
146
147 while (!IS_EOFCL(fmp, cl)) {
148 sec = cl_to_sec(fmp, cl);
149 for (i = 0; i < fmp->sec_per_cl; i++) {
150 error = fat_lookup_dirent(fmp, sec, fat_name,
151 np);
152 if (error != EAGAIN)
153 return error;
154 sec++;
155 }
156 error = fat_next_cluster(fmp, cl, &cl);
157 if (error)
158 return error;
159 }
160 }
161 return ENOENT;
162 }
163
164
165
166
167
168
169
170
171
172
173
174 static int
175 fat_get_dirent(struct fatfsmount *fmp, u_long sec, int target, int *index,
176 struct fatfs_node *np)
177 {
178 struct fat_dirent *de;
179 int error, i;
180
181 error = fat_read_dirent(fmp, sec);
182 if (error)
183 return error;
184
185 de = (struct fat_dirent *)fmp->dir_buf;
186 for (i = 0; i < DIR_PER_SEC; i++) {
187 if (IS_EMPTY(de))
188 return ENOENT;
189 if (!IS_DELETED(de) && !IS_VOL(de)) {
190
191 if (*index == target) {
192 *(&np->dirent) = *de;
193 np->sector = sec;
194 np->offset = sizeof(struct fat_dirent) * i;
195 DPRINTF(("fat_get_dirent: found index=%d\n", *index));
196 return 0;
197 }
198 (*index)++;
199 }
200 DPRINTF(("fat_get_dirent: %s\n", de->name));
201 de++;
202 }
203 return EAGAIN;
204 }
205
206
207
208
209
210
211
212
213 int
214 fatfs_get_node(vnode_t dvp, int index, struct fatfs_node *np)
215 {
216 struct fatfsmount *fmp;
217 u_long cl, sec;
218 int i, cur_index, error;
219
220 fmp = (struct fatfsmount *)dvp->v_mount->m_data;
221 cl = dvp->v_blkno;
222 cur_index = 0;
223
224 DPRINTF(("fatfs_get_node: index=%d\n", index));
225
226 if (cl == CL_ROOT) {
227
228 for (sec = fmp->root_start; sec < fmp->data_start; sec++) {
229 error = fat_get_dirent(fmp, sec, index, &cur_index, np);
230 if (error != EAGAIN)
231 return error;
232 }
233 } else {
234
235 while (!IS_EOFCL(fmp, cl)) {
236 sec = cl_to_sec(fmp, cl);
237 for (i = 0; i < fmp->sec_per_cl; i++) {
238 error = fat_get_dirent(fmp, sec, index,
239 &cur_index, np);
240 if (error != EAGAIN)
241 return error;
242 sec++;
243 }
244 error = fat_next_cluster(fmp, cl, &cl);
245 if (error)
246 return error;
247 }
248 }
249 return ENOENT;
250 }
251
252
253
254
255
256
257
258
259 static int
260 fat_add_dirent(struct fatfsmount *fmp, u_long sec, struct fatfs_node *np)
261 {
262 struct fat_dirent *de;
263 int error, i;
264
265 error = fat_read_dirent(fmp, sec);
266 if (error)
267 return error;
268
269 de = (struct fat_dirent *)fmp->dir_buf;
270 for (i = 0; i < DIR_PER_SEC; i++) {
271 if (IS_DELETED(de) || IS_EMPTY(de))
272 goto found;
273 DPRINTF(("fat_add_dirent: scan %s\n", de->name));
274 de++;
275 }
276 return ENOENT;
277
278 found:
279 DPRINTF(("fat_add_dirent: found. sec=%d\n", sec));
280 memcpy(de, &np->dirent, sizeof(struct fat_dirent));
281 error = fat_write_dirent(fmp, sec);
282 return error;
283 }
284
285
286
287
288
289
290
291 int
292 fatfs_add_node(vnode_t dvp, struct fatfs_node *np)
293 {
294 struct fatfsmount *fmp;
295 u_long cl, sec;
296 int i, error;
297 u_long next;
298
299 fmp = (struct fatfsmount *)dvp->v_mount->m_data;
300 cl = dvp->v_blkno;
301
302 DPRINTF(("fatfs_add_node: cl=%d\n", cl));
303
304 if (cl == CL_ROOT) {
305
306 for (sec = fmp->root_start; sec < fmp->data_start; sec++) {
307 error = fat_add_dirent(fmp, sec, np);
308 if (error != ENOENT)
309 return error;
310 }
311 } else {
312
313 while (!IS_EOFCL(fmp, cl)) {
314 sec = cl_to_sec(fmp, cl);
315 for (i = 0; i < fmp->sec_per_cl; i++) {
316 error = fat_add_dirent(fmp, sec, np);
317 if (error != ENOENT)
318 return error;
319 sec++;
320 }
321 error = fat_next_cluster(fmp, cl, &next);
322 if (error)
323 return error;
324 cl = next;
325 }
326
327 DPRINTF(("fatfs_add_node: expand dir\n"));
328 error = fat_expand_dir(fmp, cl, &next);
329 if (error)
330 return error;
331
332
333 memset(fmp->dir_buf, 0, SEC_SIZE);
334 sec = cl_to_sec(fmp, next);
335 for (i = 0; i < fmp->sec_per_cl; i++) {
336 error = fat_write_dirent(fmp, sec);
337 if (error)
338 return error;
339 sec++;
340 }
341
342 sec = cl_to_sec(fmp, next);
343 error = fat_add_dirent(fmp, sec, np);
344 return error;
345 }
346 return ENOENT;
347 }
348
349
350
351
352
353
354 int
355 fatfs_put_node(struct fatfsmount *fmp, struct fatfs_node *np)
356 {
357 int error;
358
359 error = fat_read_dirent(fmp, np->sector);
360 if (error)
361 return error;
362
363 memcpy(fmp->dir_buf + np->offset, &np->dirent,
364 sizeof(struct fat_dirent));
365
366 error = fat_write_dirent(fmp, np->sector);
367 return error;
368 }
369
|