Commit ad49488ffb0dd6357139f74a6b88c0b51e1ac215
Committed by
Tom Rini
1 parent
908d006ba5
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
jffs2: remove unused code files
I failed to find where these two files are used and a few test compile runs with JFFS2 enabled succeeded also without these.
Showing 2 changed files with 0 additions and 1169 deletions Side-by-side Diff
fs/jffs2/jffs2_nand_1pass.c
Changes suppressed. Click to show
1 | -#include <common.h> | |
2 | - | |
3 | -#include <malloc.h> | |
4 | -#include <linux/stat.h> | |
5 | -#include <linux/time.h> | |
6 | - | |
7 | -#include <jffs2/jffs2.h> | |
8 | -#include <jffs2/jffs2_1pass.h> | |
9 | -#include <nand.h> | |
10 | - | |
11 | -#include "jffs2_nand_private.h" | |
12 | - | |
13 | -#define NODE_CHUNK 1024 /* size of memory allocation chunk in b_nodes */ | |
14 | - | |
15 | -/* Debugging switches */ | |
16 | -#undef DEBUG_DIRENTS /* print directory entry list after scan */ | |
17 | -#undef DEBUG_FRAGMENTS /* print fragment list after scan */ | |
18 | -#undef DEBUG /* enable debugging messages */ | |
19 | - | |
20 | -#ifdef DEBUG | |
21 | -# define DEBUGF(fmt,args...) printf(fmt ,##args) | |
22 | -#else | |
23 | -# define DEBUGF(fmt,args...) | |
24 | -#endif | |
25 | - | |
26 | -static struct mtd_info *mtd; | |
27 | - | |
28 | -/* Compression names */ | |
29 | -static char *compr_names[] = { | |
30 | - "NONE", | |
31 | - "ZERO", | |
32 | - "RTIME", | |
33 | - "RUBINMIPS", | |
34 | - "COPY", | |
35 | - "DYNRUBIN", | |
36 | - "ZLIB", | |
37 | -#if defined(CONFIG_JFFS2_LZO) | |
38 | - "LZO", | |
39 | -#endif | |
40 | -}; | |
41 | - | |
42 | -/* Spinning wheel */ | |
43 | -static char spinner[] = { '|', '/', '-', '\\' }; | |
44 | - | |
45 | -/* Memory management */ | |
46 | -struct mem_block { | |
47 | - unsigned index; | |
48 | - struct mem_block *next; | |
49 | - char nodes[0]; | |
50 | -}; | |
51 | - | |
52 | -static void | |
53 | -free_nodes(struct b_list *list) | |
54 | -{ | |
55 | - while (list->listMemBase != NULL) { | |
56 | - struct mem_block *next = list->listMemBase->next; | |
57 | - free(list->listMemBase); | |
58 | - list->listMemBase = next; | |
59 | - } | |
60 | -} | |
61 | - | |
62 | -static struct b_node * | |
63 | -add_node(struct b_list *list, int size) | |
64 | -{ | |
65 | - u32 index = 0; | |
66 | - struct mem_block *memBase; | |
67 | - struct b_node *b; | |
68 | - | |
69 | - memBase = list->listMemBase; | |
70 | - if (memBase != NULL) | |
71 | - index = memBase->index; | |
72 | - | |
73 | - if (memBase == NULL || index >= NODE_CHUNK) { | |
74 | - /* we need more space before we continue */ | |
75 | - memBase = mmalloc(sizeof(struct mem_block) + NODE_CHUNK * size); | |
76 | - if (memBase == NULL) { | |
77 | - putstr("add_node: malloc failed\n"); | |
78 | - return NULL; | |
79 | - } | |
80 | - memBase->next = list->listMemBase; | |
81 | - index = 0; | |
82 | - } | |
83 | - /* now we have room to add it. */ | |
84 | - b = (struct b_node *)&memBase->nodes[size * index]; | |
85 | - index ++; | |
86 | - | |
87 | - memBase->index = index; | |
88 | - list->listMemBase = memBase; | |
89 | - list->listCount++; | |
90 | - return b; | |
91 | -} | |
92 | - | |
93 | -static struct b_node * | |
94 | -insert_node(struct b_list *list, struct b_node *new) | |
95 | -{ | |
96 | -#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS | |
97 | - struct b_node *b, *prev; | |
98 | - | |
99 | - if (list->listTail != NULL && list->listCompare(new, list->listTail)) | |
100 | - prev = list->listTail; | |
101 | - else if (list->listLast != NULL && list->listCompare(new, list->listLast)) | |
102 | - prev = list->listLast; | |
103 | - else | |
104 | - prev = NULL; | |
105 | - | |
106 | - for (b = (prev ? prev->next : list->listHead); | |
107 | - b != NULL && list->listCompare(new, b); | |
108 | - prev = b, b = b->next) { | |
109 | - list->listLoops++; | |
110 | - } | |
111 | - if (b != NULL) | |
112 | - list->listLast = prev; | |
113 | - | |
114 | - if (b != NULL) { | |
115 | - new->next = b; | |
116 | - if (prev != NULL) | |
117 | - prev->next = new; | |
118 | - else | |
119 | - list->listHead = new; | |
120 | - } else | |
121 | -#endif | |
122 | - { | |
123 | - new->next = (struct b_node *) NULL; | |
124 | - if (list->listTail != NULL) { | |
125 | - list->listTail->next = new; | |
126 | - list->listTail = new; | |
127 | - } else { | |
128 | - list->listTail = list->listHead = new; | |
129 | - } | |
130 | - } | |
131 | - | |
132 | - return new; | |
133 | -} | |
134 | - | |
135 | -static struct b_node * | |
136 | -insert_inode(struct b_list *list, struct jffs2_raw_inode *node, u32 offset) | |
137 | -{ | |
138 | - struct b_inode *new; | |
139 | - | |
140 | - if (!(new = (struct b_inode *)add_node(list, sizeof(struct b_inode)))) { | |
141 | - putstr("add_node failed!\r\n"); | |
142 | - return NULL; | |
143 | - } | |
144 | - new->offset = offset; | |
145 | - new->version = node->version; | |
146 | - new->ino = node->ino; | |
147 | - new->isize = node->isize; | |
148 | - new->csize = node->csize; | |
149 | - | |
150 | - return insert_node(list, (struct b_node *)new); | |
151 | -} | |
152 | - | |
153 | -static struct b_node * | |
154 | -insert_dirent(struct b_list *list, struct jffs2_raw_dirent *node, u32 offset) | |
155 | -{ | |
156 | - struct b_dirent *new; | |
157 | - | |
158 | - if (!(new = (struct b_dirent *)add_node(list, sizeof(struct b_dirent)))) { | |
159 | - putstr("add_node failed!\r\n"); | |
160 | - return NULL; | |
161 | - } | |
162 | - new->offset = offset; | |
163 | - new->version = node->version; | |
164 | - new->pino = node->pino; | |
165 | - new->ino = node->ino; | |
166 | - new->nhash = full_name_hash(node->name, node->nsize); | |
167 | - new->nsize = node->nsize; | |
168 | - new->type = node->type; | |
169 | - | |
170 | - return insert_node(list, (struct b_node *)new); | |
171 | -} | |
172 | - | |
173 | -#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS | |
174 | -/* Sort data entries with the latest version last, so that if there | |
175 | - * is overlapping data the latest version will be used. | |
176 | - */ | |
177 | -static int compare_inodes(struct b_node *new, struct b_node *old) | |
178 | -{ | |
179 | - struct jffs2_raw_inode ojNew; | |
180 | - struct jffs2_raw_inode ojOld; | |
181 | - struct jffs2_raw_inode *jNew = | |
182 | - (struct jffs2_raw_inode *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); | |
183 | - struct jffs2_raw_inode *jOld = | |
184 | - (struct jffs2_raw_inode *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); | |
185 | - | |
186 | - return jNew->version > jOld->version; | |
187 | -} | |
188 | - | |
189 | -/* Sort directory entries so all entries in the same directory | |
190 | - * with the same name are grouped together, with the latest version | |
191 | - * last. This makes it easy to eliminate all but the latest version | |
192 | - * by marking the previous version dead by setting the inode to 0. | |
193 | - */ | |
194 | -static int compare_dirents(struct b_node *new, struct b_node *old) | |
195 | -{ | |
196 | - struct jffs2_raw_dirent ojNew; | |
197 | - struct jffs2_raw_dirent ojOld; | |
198 | - struct jffs2_raw_dirent *jNew = | |
199 | - (struct jffs2_raw_dirent *)get_fl_mem(new->offset, sizeof(ojNew), &ojNew); | |
200 | - struct jffs2_raw_dirent *jOld = | |
201 | - (struct jffs2_raw_dirent *)get_fl_mem(old->offset, sizeof(ojOld), &ojOld); | |
202 | - int cmp; | |
203 | - | |
204 | - /* ascending sort by pino */ | |
205 | - if (jNew->pino != jOld->pino) | |
206 | - return jNew->pino > jOld->pino; | |
207 | - | |
208 | - /* pino is the same, so use ascending sort by nsize, so | |
209 | - * we don't do strncmp unless we really must. | |
210 | - */ | |
211 | - if (jNew->nsize != jOld->nsize) | |
212 | - return jNew->nsize > jOld->nsize; | |
213 | - | |
214 | - /* length is also the same, so use ascending sort by name | |
215 | - */ | |
216 | - cmp = strncmp(jNew->name, jOld->name, jNew->nsize); | |
217 | - if (cmp != 0) | |
218 | - return cmp > 0; | |
219 | - | |
220 | - /* we have duplicate names in this directory, so use ascending | |
221 | - * sort by version | |
222 | - */ | |
223 | - if (jNew->version > jOld->version) { | |
224 | - /* since jNew is newer, we know jOld is not valid, so | |
225 | - * mark it with inode 0 and it will not be used | |
226 | - */ | |
227 | - jOld->ino = 0; | |
228 | - return 1; | |
229 | - } | |
230 | - | |
231 | - return 0; | |
232 | -} | |
233 | -#endif | |
234 | - | |
235 | -static u32 | |
236 | -jffs_init_1pass_list(struct part_info *part) | |
237 | -{ | |
238 | - struct b_lists *pL; | |
239 | - | |
240 | - if (part->jffs2_priv != NULL) { | |
241 | - pL = (struct b_lists *)part->jffs2_priv; | |
242 | - free_nodes(&pL->frag); | |
243 | - free_nodes(&pL->dir); | |
244 | - free(pL); | |
245 | - } | |
246 | - if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) { | |
247 | - pL = (struct b_lists *)part->jffs2_priv; | |
248 | - | |
249 | - memset(pL, 0, sizeof(*pL)); | |
250 | -#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS | |
251 | - pL->dir.listCompare = compare_dirents; | |
252 | - pL->frag.listCompare = compare_inodes; | |
253 | -#endif | |
254 | - } | |
255 | - return 0; | |
256 | -} | |
257 | - | |
258 | -/* find the inode from the slashless name given a parent */ | |
259 | -static long | |
260 | -jffs2_1pass_read_inode(struct b_lists *pL, u32 ino, char *dest, | |
261 | - struct stat *stat) | |
262 | -{ | |
263 | - struct b_inode *jNode; | |
264 | - u32 totalSize = 0; | |
265 | - u32 latestVersion = 0; | |
266 | - long ret; | |
267 | - | |
268 | -#ifdef CONFIG_SYS_JFFS2_SORT_FRAGMENTS | |
269 | - /* Find file size before loading any data, so fragments that | |
270 | - * start past the end of file can be ignored. A fragment | |
271 | - * that is partially in the file is loaded, so extra data may | |
272 | - * be loaded up to the next 4K boundary above the file size. | |
273 | - * This shouldn't cause trouble when loading kernel images, so | |
274 | - * we will live with it. | |
275 | - */ | |
276 | - for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { | |
277 | - if ((ino == jNode->ino)) { | |
278 | - /* get actual file length from the newest node */ | |
279 | - if (jNode->version >= latestVersion) { | |
280 | - totalSize = jNode->isize; | |
281 | - latestVersion = jNode->version; | |
282 | - } | |
283 | - } | |
284 | - } | |
285 | -#endif | |
286 | - | |
287 | - for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { | |
288 | - if ((ino != jNode->ino)) | |
289 | - continue; | |
290 | -#ifndef CONFIG_SYS_JFFS2_SORT_FRAGMENTS | |
291 | - /* get actual file length from the newest node */ | |
292 | - if (jNode->version >= latestVersion) { | |
293 | - totalSize = jNode->isize; | |
294 | - latestVersion = jNode->version; | |
295 | - } | |
296 | -#endif | |
297 | - if (dest || stat) { | |
298 | - char *src, *dst; | |
299 | - char data[4096 + sizeof(struct jffs2_raw_inode)]; | |
300 | - struct jffs2_raw_inode *inode; | |
301 | - size_t len; | |
302 | - | |
303 | - inode = (struct jffs2_raw_inode *)&data; | |
304 | - len = sizeof(struct jffs2_raw_inode); | |
305 | - if (dest) | |
306 | - len += jNode->csize; | |
307 | - nand_read(mtd, jNode->offset, &len, inode); | |
308 | - /* ignore data behind latest known EOF */ | |
309 | - if (inode->offset > totalSize) | |
310 | - continue; | |
311 | - | |
312 | - if (stat) { | |
313 | - stat->st_mtime = inode->mtime; | |
314 | - stat->st_mode = inode->mode; | |
315 | - stat->st_ino = inode->ino; | |
316 | - stat->st_size = totalSize; | |
317 | - } | |
318 | - | |
319 | - if (!dest) | |
320 | - continue; | |
321 | - | |
322 | - src = ((char *) inode) + sizeof(struct jffs2_raw_inode); | |
323 | - dst = (char *) (dest + inode->offset); | |
324 | - | |
325 | - switch (inode->compr) { | |
326 | - case JFFS2_COMPR_NONE: | |
327 | - ret = 0; | |
328 | - memcpy(dst, src, inode->dsize); | |
329 | - break; | |
330 | - case JFFS2_COMPR_ZERO: | |
331 | - ret = 0; | |
332 | - memset(dst, 0, inode->dsize); | |
333 | - break; | |
334 | - case JFFS2_COMPR_RTIME: | |
335 | - ret = 0; | |
336 | - rtime_decompress(src, dst, inode->csize, inode->dsize); | |
337 | - break; | |
338 | - case JFFS2_COMPR_DYNRUBIN: | |
339 | - /* this is slow but it works */ | |
340 | - ret = 0; | |
341 | - dynrubin_decompress(src, dst, inode->csize, inode->dsize); | |
342 | - break; | |
343 | - case JFFS2_COMPR_ZLIB: | |
344 | - ret = zlib_decompress(src, dst, inode->csize, inode->dsize); | |
345 | - break; | |
346 | -#if defined(CONFIG_JFFS2_LZO) | |
347 | - case JFFS2_COMPR_LZO: | |
348 | - ret = lzo_decompress(src, dst, inode->csize, inode->dsize); | |
349 | - break; | |
350 | -#endif | |
351 | - default: | |
352 | - /* unknown */ | |
353 | - putLabeledWord("UNKNOWN COMPRESSION METHOD = ", inode->compr); | |
354 | - return -1; | |
355 | - } | |
356 | - } | |
357 | - } | |
358 | - | |
359 | - return totalSize; | |
360 | -} | |
361 | - | |
362 | -/* find the inode from the slashless name given a parent */ | |
363 | -static u32 | |
364 | -jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) | |
365 | -{ | |
366 | - struct b_dirent *jDir; | |
367 | - int len = strlen(name); /* name is assumed slash free */ | |
368 | - unsigned int nhash = full_name_hash(name, len); | |
369 | - u32 version = 0; | |
370 | - u32 inode = 0; | |
371 | - | |
372 | - /* we need to search all and return the inode with the highest version */ | |
373 | - for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { | |
374 | - if ((pino == jDir->pino) && (jDir->ino) && /* 0 for unlink */ | |
375 | - (len == jDir->nsize) && (nhash == jDir->nhash)) { | |
376 | - /* TODO: compare name */ | |
377 | - if (jDir->version < version) | |
378 | - continue; | |
379 | - | |
380 | - if (jDir->version == version && inode != 0) { | |
381 | - /* I'm pretty sure this isn't legal */ | |
382 | - putstr(" ** ERROR ** "); | |
383 | -/* putnstr(jDir->name, jDir->nsize); */ | |
384 | -/* putLabeledWord(" has dup version =", version); */ | |
385 | - } | |
386 | - inode = jDir->ino; | |
387 | - version = jDir->version; | |
388 | - } | |
389 | - } | |
390 | - return inode; | |
391 | -} | |
392 | - | |
393 | -char *mkmodestr(unsigned long mode, char *str) | |
394 | -{ | |
395 | - static const char *l = "xwr"; | |
396 | - int mask = 1, i; | |
397 | - char c; | |
398 | - | |
399 | - switch (mode & S_IFMT) { | |
400 | - case S_IFDIR: str[0] = 'd'; break; | |
401 | - case S_IFBLK: str[0] = 'b'; break; | |
402 | - case S_IFCHR: str[0] = 'c'; break; | |
403 | - case S_IFIFO: str[0] = 'f'; break; | |
404 | - case S_IFLNK: str[0] = 'l'; break; | |
405 | - case S_IFSOCK: str[0] = 's'; break; | |
406 | - case S_IFREG: str[0] = '-'; break; | |
407 | - default: str[0] = '?'; | |
408 | - } | |
409 | - | |
410 | - for(i = 0; i < 9; i++) { | |
411 | - c = l[i%3]; | |
412 | - str[9-i] = (mode & mask)?c:'-'; | |
413 | - mask = mask<<1; | |
414 | - } | |
415 | - | |
416 | - if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S'; | |
417 | - if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S'; | |
418 | - if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T'; | |
419 | - str[10] = '\0'; | |
420 | - return str; | |
421 | -} | |
422 | - | |
423 | -static inline void dump_stat(struct stat *st, const char *name) | |
424 | -{ | |
425 | - char str[20]; | |
426 | - char s[64], *p; | |
427 | - | |
428 | - if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */ | |
429 | - st->st_mtime = 1; | |
430 | - | |
431 | - ctime_r(&st->st_mtime, s/*,64*/); /* newlib ctime doesn't have buflen */ | |
432 | - | |
433 | - if ((p = strchr(s,'\n')) != NULL) *p = '\0'; | |
434 | - if ((p = strchr(s,'\r')) != NULL) *p = '\0'; | |
435 | - | |
436 | -/* | |
437 | - printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str), | |
438 | - st->st_size, s, name); | |
439 | -*/ | |
440 | - | |
441 | - printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name); | |
442 | -} | |
443 | - | |
444 | -static inline int | |
445 | -dump_inode(struct b_lists *pL, struct b_dirent *d, struct b_inode *i) | |
446 | -{ | |
447 | - char fname[JFFS2_MAX_NAME_LEN + 1]; | |
448 | - struct stat st; | |
449 | - size_t len; | |
450 | - | |
451 | - if(!d || !i) return -1; | |
452 | - len = d->nsize; | |
453 | - nand_read(mtd, d->offset + sizeof(struct jffs2_raw_dirent), | |
454 | - &len, &fname); | |
455 | - fname[d->nsize] = '\0'; | |
456 | - | |
457 | - memset(&st, 0, sizeof(st)); | |
458 | - | |
459 | - jffs2_1pass_read_inode(pL, i->ino, NULL, &st); | |
460 | - | |
461 | - dump_stat(&st, fname); | |
462 | -/* FIXME | |
463 | - if (d->type == DT_LNK) { | |
464 | - unsigned char *src = (unsigned char *) (&i[1]); | |
465 | - putstr(" -> "); | |
466 | - putnstr(src, (int)i->dsize); | |
467 | - } | |
468 | -*/ | |
469 | - putstr("\r\n"); | |
470 | - | |
471 | - return 0; | |
472 | -} | |
473 | - | |
474 | -/* list inodes with the given pino */ | |
475 | -static u32 | |
476 | -jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) | |
477 | -{ | |
478 | - struct b_dirent *jDir; | |
479 | - u32 i_version = 0; | |
480 | - | |
481 | - for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { | |
482 | - if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */ | |
483 | - struct b_inode *jNode = (struct b_inode *)pL->frag.listHead; | |
484 | - struct b_inode *i = NULL; | |
485 | - | |
486 | - while (jNode) { | |
487 | - if (jNode->ino == jDir->ino && jNode->version >= i_version) { | |
488 | - i_version = jNode->version; | |
489 | - i = jNode; | |
490 | - } | |
491 | - jNode = jNode->next; | |
492 | - } | |
493 | - dump_inode(pL, jDir, i); | |
494 | - } | |
495 | - } | |
496 | - return pino; | |
497 | -} | |
498 | - | |
499 | -static u32 | |
500 | -jffs2_1pass_search_inode(struct b_lists * pL, const char *fname, u32 pino) | |
501 | -{ | |
502 | - int i; | |
503 | - char tmp[256]; | |
504 | - char working_tmp[256]; | |
505 | - char *c; | |
506 | - | |
507 | - /* discard any leading slash */ | |
508 | - i = 0; | |
509 | - while (fname[i] == '/') | |
510 | - i++; | |
511 | - strcpy(tmp, &fname[i]); | |
512 | - | |
513 | - while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ | |
514 | - { | |
515 | - strncpy(working_tmp, tmp, c - tmp); | |
516 | - working_tmp[c - tmp] = '\0'; | |
517 | -#if 0 | |
518 | - putstr("search_inode: tmp = "); | |
519 | - putstr(tmp); | |
520 | - putstr("\r\n"); | |
521 | - putstr("search_inode: wtmp = "); | |
522 | - putstr(working_tmp); | |
523 | - putstr("\r\n"); | |
524 | - putstr("search_inode: c = "); | |
525 | - putstr(c); | |
526 | - putstr("\r\n"); | |
527 | -#endif | |
528 | - for (i = 0; i < strlen(c) - 1; i++) | |
529 | - tmp[i] = c[i + 1]; | |
530 | - tmp[i] = '\0'; | |
531 | -#if 0 | |
532 | - putstr("search_inode: post tmp = "); | |
533 | - putstr(tmp); | |
534 | - putstr("\r\n"); | |
535 | -#endif | |
536 | - | |
537 | - if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) { | |
538 | - putstr("find_inode failed for name="); | |
539 | - putstr(working_tmp); | |
540 | - putstr("\r\n"); | |
541 | - return 0; | |
542 | - } | |
543 | - } | |
544 | - /* this is for the bare filename, directories have already been mapped */ | |
545 | - if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { | |
546 | - putstr("find_inode failed for name="); | |
547 | - putstr(tmp); | |
548 | - putstr("\r\n"); | |
549 | - return 0; | |
550 | - } | |
551 | - return pino; | |
552 | - | |
553 | -} | |
554 | - | |
555 | -static u32 | |
556 | -jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) | |
557 | -{ | |
558 | - struct b_dirent *jDir; | |
559 | - struct b_inode *jNode; | |
560 | - u8 jDirFoundType = 0; | |
561 | - u32 jDirFoundIno = 0; | |
562 | - u32 jDirFoundPino = 0; | |
563 | - char tmp[JFFS2_MAX_NAME_LEN + 1]; | |
564 | - u32 version = 0; | |
565 | - u32 pino; | |
566 | - | |
567 | - /* we need to search all and return the inode with the highest version */ | |
568 | - for (jDir = (struct b_dirent *)pL->dir.listHead; jDir; jDir = jDir->next) { | |
569 | - if (ino == jDir->ino) { | |
570 | - if (jDir->version < version) | |
571 | - continue; | |
572 | - | |
573 | - if (jDir->version == version && jDirFoundType) { | |
574 | - /* I'm pretty sure this isn't legal */ | |
575 | - putstr(" ** ERROR ** "); | |
576 | -/* putnstr(jDir->name, jDir->nsize); */ | |
577 | -/* putLabeledWord(" has dup version (resolve) = ", */ | |
578 | -/* version); */ | |
579 | - } | |
580 | - | |
581 | - jDirFoundType = jDir->type; | |
582 | - jDirFoundIno = jDir->ino; | |
583 | - jDirFoundPino = jDir->pino; | |
584 | - version = jDir->version; | |
585 | - } | |
586 | - } | |
587 | - /* now we found the right entry again. (shoulda returned inode*) */ | |
588 | - if (jDirFoundType != DT_LNK) | |
589 | - return jDirFoundIno; | |
590 | - | |
591 | - /* it's a soft link so we follow it again. */ | |
592 | - for (jNode = (struct b_inode *)pL->frag.listHead; jNode; jNode = jNode->next) { | |
593 | - if (jNode->ino == jDirFoundIno) { | |
594 | - size_t len = jNode->csize; | |
595 | - nand_read(mtd, | |
596 | - jNode->offset + sizeof(struct jffs2_raw_inode), | |
597 | - &len, &tmp); | |
598 | - tmp[jNode->csize] = '\0'; | |
599 | - break; | |
600 | - } | |
601 | - } | |
602 | - /* ok so the name of the new file to find is in tmp */ | |
603 | - /* if it starts with a slash it is root based else shared dirs */ | |
604 | - if (tmp[0] == '/') | |
605 | - pino = 1; | |
606 | - else | |
607 | - pino = jDirFoundPino; | |
608 | - | |
609 | - return jffs2_1pass_search_inode(pL, tmp, pino); | |
610 | -} | |
611 | - | |
612 | -static u32 | |
613 | -jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino) | |
614 | -{ | |
615 | - int i; | |
616 | - char tmp[256]; | |
617 | - char working_tmp[256]; | |
618 | - char *c; | |
619 | - | |
620 | - /* discard any leading slash */ | |
621 | - i = 0; | |
622 | - while (fname[i] == '/') | |
623 | - i++; | |
624 | - strcpy(tmp, &fname[i]); | |
625 | - working_tmp[0] = '\0'; | |
626 | - while ((c = (char *) strchr(tmp, '/'))) /* we are still dired searching */ | |
627 | - { | |
628 | - strncpy(working_tmp, tmp, c - tmp); | |
629 | - working_tmp[c - tmp] = '\0'; | |
630 | - for (i = 0; i < strlen(c) - 1; i++) | |
631 | - tmp[i] = c[i + 1]; | |
632 | - tmp[i] = '\0'; | |
633 | - /* only a failure if we arent looking at top level */ | |
634 | - if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && | |
635 | - (working_tmp[0])) { | |
636 | - putstr("find_inode failed for name="); | |
637 | - putstr(working_tmp); | |
638 | - putstr("\r\n"); | |
639 | - return 0; | |
640 | - } | |
641 | - } | |
642 | - | |
643 | - if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) { | |
644 | - putstr("find_inode failed for name="); | |
645 | - putstr(tmp); | |
646 | - putstr("\r\n"); | |
647 | - return 0; | |
648 | - } | |
649 | - /* this is for the bare filename, directories have already been mapped */ | |
650 | - if (!(pino = jffs2_1pass_list_inodes(pL, pino))) { | |
651 | - putstr("find_inode failed for name="); | |
652 | - putstr(tmp); | |
653 | - putstr("\r\n"); | |
654 | - return 0; | |
655 | - } | |
656 | - return pino; | |
657 | - | |
658 | -} | |
659 | - | |
660 | -unsigned char | |
661 | -jffs2_1pass_rescan_needed(struct part_info *part) | |
662 | -{ | |
663 | - struct b_node *b; | |
664 | - struct jffs2_unknown_node onode; | |
665 | - struct jffs2_unknown_node *node; | |
666 | - struct b_lists *pL = (struct b_lists *)part->jffs2_priv; | |
667 | - | |
668 | - if (part->jffs2_priv == 0){ | |
669 | - DEBUGF ("rescan: First time in use\n"); | |
670 | - return 1; | |
671 | - } | |
672 | - /* if we have no list, we need to rescan */ | |
673 | - if (pL->frag.listCount == 0) { | |
674 | - DEBUGF ("rescan: fraglist zero\n"); | |
675 | - return 1; | |
676 | - } | |
677 | - | |
678 | - /* or if we are scanning a new partition */ | |
679 | - if (pL->partOffset != part->offset) { | |
680 | - DEBUGF ("rescan: different partition\n"); | |
681 | - return 1; | |
682 | - } | |
683 | - | |
684 | - /* FIXME */ | |
685 | -#if 0 | |
686 | - /* but suppose someone reflashed a partition at the same offset... */ | |
687 | - b = pL->dir.listHead; | |
688 | - while (b) { | |
689 | - node = (struct jffs2_unknown_node *) get_fl_mem(b->offset, | |
690 | - sizeof(onode), &onode); | |
691 | - if (node->nodetype != JFFS2_NODETYPE_DIRENT) { | |
692 | - DEBUGF ("rescan: fs changed beneath me? (%lx)\n", | |
693 | - (unsigned long) b->offset); | |
694 | - return 1; | |
695 | - } | |
696 | - b = b->next; | |
697 | - } | |
698 | -#endif | |
699 | - return 0; | |
700 | -} | |
701 | - | |
702 | -#ifdef DEBUG_FRAGMENTS | |
703 | -static void | |
704 | -dump_fragments(struct b_lists *pL) | |
705 | -{ | |
706 | - struct b_node *b; | |
707 | - struct jffs2_raw_inode ojNode; | |
708 | - struct jffs2_raw_inode *jNode; | |
709 | - | |
710 | - putstr("\r\n\r\n******The fragment Entries******\r\n"); | |
711 | - b = pL->frag.listHead; | |
712 | - while (b) { | |
713 | - jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, | |
714 | - sizeof(ojNode), &ojNode); | |
715 | - putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset); | |
716 | - putLabeledWord("\tbuild_list: totlen = ", jNode->totlen); | |
717 | - putLabeledWord("\tbuild_list: inode = ", jNode->ino); | |
718 | - putLabeledWord("\tbuild_list: version = ", jNode->version); | |
719 | - putLabeledWord("\tbuild_list: isize = ", jNode->isize); | |
720 | - putLabeledWord("\tbuild_list: atime = ", jNode->atime); | |
721 | - putLabeledWord("\tbuild_list: offset = ", jNode->offset); | |
722 | - putLabeledWord("\tbuild_list: csize = ", jNode->csize); | |
723 | - putLabeledWord("\tbuild_list: dsize = ", jNode->dsize); | |
724 | - putLabeledWord("\tbuild_list: compr = ", jNode->compr); | |
725 | - putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr); | |
726 | - putLabeledWord("\tbuild_list: flags = ", jNode->flags); | |
727 | - putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ | |
728 | - b = b->next; | |
729 | - } | |
730 | -} | |
731 | -#endif | |
732 | - | |
733 | -#ifdef DEBUG_DIRENTS | |
734 | -static void | |
735 | -dump_dirents(struct b_lists *pL) | |
736 | -{ | |
737 | - struct b_node *b; | |
738 | - struct jffs2_raw_dirent *jDir; | |
739 | - | |
740 | - putstr("\r\n\r\n******The directory Entries******\r\n"); | |
741 | - b = pL->dir.listHead; | |
742 | - while (b) { | |
743 | - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); | |
744 | - putstr("\r\n"); | |
745 | - putnstr(jDir->name, jDir->nsize); | |
746 | - putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); | |
747 | - putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype); | |
748 | - putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc); | |
749 | - putLabeledWord("\tbuild_list: pino = ", jDir->pino); | |
750 | - putLabeledWord("\tbuild_list: version = ", jDir->version); | |
751 | - putLabeledWord("\tbuild_list: ino = ", jDir->ino); | |
752 | - putLabeledWord("\tbuild_list: mctime = ", jDir->mctime); | |
753 | - putLabeledWord("\tbuild_list: nsize = ", jDir->nsize); | |
754 | - putLabeledWord("\tbuild_list: type = ", jDir->type); | |
755 | - putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc); | |
756 | - putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); | |
757 | - putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ | |
758 | - b = b->next; | |
759 | - put_fl_mem(jDir); | |
760 | - } | |
761 | -} | |
762 | -#endif | |
763 | - | |
764 | -static int | |
765 | -jffs2_fill_scan_buf(struct mtd_info *mtd, unsigned char *buf, | |
766 | - unsigned ofs, unsigned len) | |
767 | -{ | |
768 | - int ret; | |
769 | - unsigned olen; | |
770 | - | |
771 | - olen = len; | |
772 | - ret = nand_read(mtd, ofs, &olen, buf); | |
773 | - if (ret) { | |
774 | - printf("nand_read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret); | |
775 | - return ret; | |
776 | - } | |
777 | - if (olen < len) { | |
778 | - printf("Read at 0x%x gave only 0x%x bytes\n", ofs, olen); | |
779 | - return -1; | |
780 | - } | |
781 | - return 0; | |
782 | -} | |
783 | - | |
784 | -#define EMPTY_SCAN_SIZE 1024 | |
785 | -static u32 | |
786 | -jffs2_1pass_build_lists(struct part_info * part) | |
787 | -{ | |
788 | - struct b_lists *pL; | |
789 | - struct jffs2_unknown_node *node; | |
790 | - unsigned nr_blocks, sectorsize, ofs, offset; | |
791 | - char *buf; | |
792 | - int i; | |
793 | - u32 counter = 0; | |
794 | - u32 counter4 = 0; | |
795 | - u32 counterF = 0; | |
796 | - u32 counterN = 0; | |
797 | - | |
798 | - struct mtdids *id = part->dev->id; | |
799 | - mtd = get_nand_dev_by_index(id->num); | |
800 | - if (!mtd) { | |
801 | - pr_err("\nno NAND devices available\n"); | |
802 | - return 0; | |
803 | - } | |
804 | - | |
805 | - /* if we are building a list we need to refresh the cache. */ | |
806 | - jffs_init_1pass_list(part); | |
807 | - pL = (struct b_lists *)part->jffs2_priv; | |
808 | - pL->partOffset = part->offset; | |
809 | - puts ("Scanning JFFS2 FS: "); | |
810 | - | |
811 | - sectorsize = mtd->erasesize; | |
812 | - nr_blocks = part->size / sectorsize; | |
813 | - buf = malloc(sectorsize); | |
814 | - if (!buf) | |
815 | - return 0; | |
816 | - | |
817 | - for (i = 0; i < nr_blocks; i++) { | |
818 | - printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); | |
819 | - | |
820 | - offset = part->offset + i * sectorsize; | |
821 | - | |
822 | - if (nand_block_isbad(mtd, offset)) | |
823 | - continue; | |
824 | - | |
825 | - if (jffs2_fill_scan_buf(mtd, buf, offset, EMPTY_SCAN_SIZE)) | |
826 | - return 0; | |
827 | - | |
828 | - ofs = 0; | |
829 | - /* Scan only 4KiB of 0xFF before declaring it's empty */ | |
830 | - while (ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) | |
831 | - ofs += 4; | |
832 | - if (ofs == EMPTY_SCAN_SIZE) | |
833 | - continue; | |
834 | - | |
835 | - if (jffs2_fill_scan_buf(mtd, buf + EMPTY_SCAN_SIZE, offset + EMPTY_SCAN_SIZE, sectorsize - EMPTY_SCAN_SIZE)) | |
836 | - return 0; | |
837 | - offset += ofs; | |
838 | - | |
839 | - while (ofs < sectorsize - sizeof(struct jffs2_unknown_node)) { | |
840 | - node = (struct jffs2_unknown_node *)&buf[ofs]; | |
841 | - if (node->magic != JFFS2_MAGIC_BITMASK || !hdr_crc(node)) { | |
842 | - offset += 4; | |
843 | - ofs += 4; | |
844 | - counter4++; | |
845 | - continue; | |
846 | - } | |
847 | - /* if its a fragment add it */ | |
848 | - if (node->nodetype == JFFS2_NODETYPE_INODE && | |
849 | - inode_crc((struct jffs2_raw_inode *) node)) { | |
850 | - if (insert_inode(&pL->frag, (struct jffs2_raw_inode *) node, | |
851 | - offset) == NULL) { | |
852 | - return 0; | |
853 | - } | |
854 | - } else if (node->nodetype == JFFS2_NODETYPE_DIRENT && | |
855 | - dirent_crc((struct jffs2_raw_dirent *) node) && | |
856 | - dirent_name_crc((struct jffs2_raw_dirent *) node)) { | |
857 | - if (! (counterN%100)) | |
858 | - puts ("\b\b. "); | |
859 | - if (insert_dirent(&pL->dir, (struct jffs2_raw_dirent *) node, | |
860 | - offset) == NULL) { | |
861 | - return 0; | |
862 | - } | |
863 | - counterN++; | |
864 | - } else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) { | |
865 | - if (node->totlen != sizeof(struct jffs2_unknown_node)) | |
866 | - printf("OOPS Cleanmarker has bad size " | |
867 | - "%d != %zu\n", | |
868 | - node->totlen, | |
869 | - sizeof(struct jffs2_unknown_node)); | |
870 | - } else if (node->nodetype == JFFS2_NODETYPE_PADDING) { | |
871 | - if (node->totlen < sizeof(struct jffs2_unknown_node)) | |
872 | - printf("OOPS Padding has bad size " | |
873 | - "%d < %zu\n", | |
874 | - node->totlen, | |
875 | - sizeof(struct jffs2_unknown_node)); | |
876 | - } else { | |
877 | - printf("Unknown node type: %x len %d offset 0x%x\n", | |
878 | - node->nodetype, | |
879 | - node->totlen, offset); | |
880 | - } | |
881 | - offset += ((node->totlen + 3) & ~3); | |
882 | - ofs += ((node->totlen + 3) & ~3); | |
883 | - counterF++; | |
884 | - } | |
885 | - } | |
886 | - | |
887 | - putstr("\b\b done.\r\n"); /* close off the dots */ | |
888 | - | |
889 | -#if 0 | |
890 | - putLabeledWord("dir entries = ", pL->dir.listCount); | |
891 | - putLabeledWord("frag entries = ", pL->frag.listCount); | |
892 | - putLabeledWord("+4 increments = ", counter4); | |
893 | - putLabeledWord("+file_offset increments = ", counterF); | |
894 | -#endif | |
895 | - | |
896 | -#ifdef DEBUG_DIRENTS | |
897 | - dump_dirents(pL); | |
898 | -#endif | |
899 | - | |
900 | -#ifdef DEBUG_FRAGMENTS | |
901 | - dump_fragments(pL); | |
902 | -#endif | |
903 | - | |
904 | - /* give visual feedback that we are done scanning the flash */ | |
905 | - led_blink(0x0, 0x0, 0x1, 0x1); /* off, forever, on 100ms, off 100ms */ | |
906 | - free(buf); | |
907 | - | |
908 | - return 1; | |
909 | -} | |
910 | - | |
911 | - | |
912 | -static u32 | |
913 | -jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL) | |
914 | -{ | |
915 | - struct b_node *b; | |
916 | - struct jffs2_raw_inode ojNode; | |
917 | - struct jffs2_raw_inode *jNode; | |
918 | - int i; | |
919 | - | |
920 | - for (i = 0; i < JFFS2_NUM_COMPR; i++) { | |
921 | - piL->compr_info[i].num_frags = 0; | |
922 | - piL->compr_info[i].compr_sum = 0; | |
923 | - piL->compr_info[i].decompr_sum = 0; | |
924 | - } | |
925 | -/* FIXME | |
926 | - b = pL->frag.listHead; | |
927 | - while (b) { | |
928 | - jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, | |
929 | - sizeof(ojNode), &ojNode); | |
930 | - if (jNode->compr < JFFS2_NUM_COMPR) { | |
931 | - piL->compr_info[jNode->compr].num_frags++; | |
932 | - piL->compr_info[jNode->compr].compr_sum += jNode->csize; | |
933 | - piL->compr_info[jNode->compr].decompr_sum += jNode->dsize; | |
934 | - } | |
935 | - b = b->next; | |
936 | - } | |
937 | -*/ | |
938 | - return 0; | |
939 | -} | |
940 | - | |
941 | - | |
942 | -static struct b_lists * | |
943 | -jffs2_get_list(struct part_info * part, const char *who) | |
944 | -{ | |
945 | - if (jffs2_1pass_rescan_needed(part)) { | |
946 | - if (!jffs2_1pass_build_lists(part)) { | |
947 | - printf("%s: Failed to scan JFFSv2 file structure\n", who); | |
948 | - return NULL; | |
949 | - } | |
950 | - } | |
951 | - return (struct b_lists *)part->jffs2_priv; | |
952 | -} | |
953 | - | |
954 | - | |
955 | -/* Print directory / file contents */ | |
956 | -u32 | |
957 | -jffs2_1pass_ls(struct part_info * part, const char *fname) | |
958 | -{ | |
959 | - struct b_lists *pl; | |
960 | - long ret = 0; | |
961 | - u32 inode; | |
962 | - | |
963 | - if (! (pl = jffs2_get_list(part, "ls"))) | |
964 | - return 0; | |
965 | - | |
966 | - if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) { | |
967 | - putstr("ls: Failed to scan jffs2 file structure\r\n"); | |
968 | - return 0; | |
969 | - } | |
970 | - | |
971 | -#if 0 | |
972 | - putLabeledWord("found file at inode = ", inode); | |
973 | - putLabeledWord("read_inode returns = ", ret); | |
974 | -#endif | |
975 | - | |
976 | - return ret; | |
977 | -} | |
978 | - | |
979 | - | |
980 | -/* Load a file from flash into memory. fname can be a full path */ | |
981 | -u32 | |
982 | -jffs2_1pass_load(char *dest, struct part_info * part, const char *fname) | |
983 | -{ | |
984 | - | |
985 | - struct b_lists *pl; | |
986 | - long ret = 0; | |
987 | - u32 inode; | |
988 | - | |
989 | - if (! (pl = jffs2_get_list(part, "load"))) | |
990 | - return 0; | |
991 | - | |
992 | - if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) { | |
993 | - putstr("load: Failed to find inode\r\n"); | |
994 | - return 0; | |
995 | - } | |
996 | - | |
997 | - /* Resolve symlinks */ | |
998 | - if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) { | |
999 | - putstr("load: Failed to resolve inode structure\r\n"); | |
1000 | - return 0; | |
1001 | - } | |
1002 | - | |
1003 | - if ((ret = jffs2_1pass_read_inode(pl, inode, dest, NULL)) < 0) { | |
1004 | - putstr("load: Failed to read inode\r\n"); | |
1005 | - return 0; | |
1006 | - } | |
1007 | - | |
1008 | - DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname, | |
1009 | - (unsigned long) dest, ret); | |
1010 | - return ret; | |
1011 | -} | |
1012 | - | |
1013 | -/* Return information about the fs on this partition */ | |
1014 | -u32 | |
1015 | -jffs2_1pass_info(struct part_info * part) | |
1016 | -{ | |
1017 | - struct b_jffs2_info info; | |
1018 | - struct b_lists *pl; | |
1019 | - int i; | |
1020 | - | |
1021 | - if (! (pl = jffs2_get_list(part, "info"))) | |
1022 | - return 0; | |
1023 | - | |
1024 | - jffs2_1pass_fill_info(pl, &info); | |
1025 | - for (i = 0; i < JFFS2_NUM_COMPR; i++) { | |
1026 | - printf ("Compression: %s\n" | |
1027 | - "\tfrag count: %d\n" | |
1028 | - "\tcompressed sum: %d\n" | |
1029 | - "\tuncompressed sum: %d\n", | |
1030 | - compr_names[i], | |
1031 | - info.compr_info[i].num_frags, | |
1032 | - info.compr_info[i].compr_sum, | |
1033 | - info.compr_info[i].decompr_sum); | |
1034 | - } | |
1035 | - return 1; | |
1036 | -} |
fs/jffs2/jffs2_nand_private.h
1 | -#ifndef jffs2_private_h | |
2 | -#define jffs2_private_h | |
3 | - | |
4 | -#include <jffs2/jffs2.h> | |
5 | - | |
6 | -struct b_node { | |
7 | - struct b_node *next; | |
8 | -}; | |
9 | - | |
10 | -struct b_inode { | |
11 | - struct b_inode *next; | |
12 | - u32 offset; /* physical offset to beginning of real inode */ | |
13 | - u32 version; | |
14 | - u32 ino; | |
15 | - u32 isize; | |
16 | - u32 csize; | |
17 | -}; | |
18 | - | |
19 | -struct b_dirent { | |
20 | - struct b_dirent *next; | |
21 | - u32 offset; /* physical offset to beginning of real dirent */ | |
22 | - u32 version; | |
23 | - u32 pino; | |
24 | - u32 ino; | |
25 | - unsigned int nhash; | |
26 | - unsigned char nsize; | |
27 | - unsigned char type; | |
28 | -}; | |
29 | - | |
30 | -struct b_list { | |
31 | - struct b_node *listTail; | |
32 | - struct b_node *listHead; | |
33 | - unsigned int listCount; | |
34 | - struct mem_block *listMemBase; | |
35 | -}; | |
36 | - | |
37 | -struct b_lists { | |
38 | - char *partOffset; | |
39 | - struct b_list dir; | |
40 | - struct b_list frag; | |
41 | -}; | |
42 | - | |
43 | -struct b_compr_info { | |
44 | - u32 num_frags; | |
45 | - u32 compr_sum; | |
46 | - u32 decompr_sum; | |
47 | -}; | |
48 | - | |
49 | -struct b_jffs2_info { | |
50 | - struct b_compr_info compr_info[JFFS2_NUM_COMPR]; | |
51 | -}; | |
52 | - | |
53 | -static inline int | |
54 | -hdr_crc(struct jffs2_unknown_node *node) | |
55 | -{ | |
56 | -#if 1 | |
57 | - u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); | |
58 | -#else | |
59 | - /* what's the semantics of this? why is this here? */ | |
60 | - u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); | |
61 | - | |
62 | - crc ^= ~0; | |
63 | -#endif | |
64 | - if (node->hdr_crc != crc) { | |
65 | - return 0; | |
66 | - } else { | |
67 | - return 1; | |
68 | - } | |
69 | -} | |
70 | - | |
71 | -static inline int | |
72 | -dirent_crc(struct jffs2_raw_dirent *node) | |
73 | -{ | |
74 | - if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_dirent) - 8)) { | |
75 | - return 0; | |
76 | - } else { | |
77 | - return 1; | |
78 | - } | |
79 | -} | |
80 | - | |
81 | -static inline int | |
82 | -dirent_name_crc(struct jffs2_raw_dirent *node) | |
83 | -{ | |
84 | - if (node->name_crc != crc32_no_comp(0, (unsigned char *)&(node->name), node->nsize)) { | |
85 | - return 0; | |
86 | - } else { | |
87 | - return 1; | |
88 | - } | |
89 | -} | |
90 | - | |
91 | -static inline int | |
92 | -inode_crc(struct jffs2_raw_inode *node) | |
93 | -{ | |
94 | - if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_inode) - 8)) { | |
95 | - return 0; | |
96 | - } else { | |
97 | - return 1; | |
98 | - } | |
99 | -} | |
100 | - | |
101 | -/* Borrowed from include/linux/dcache.h */ | |
102 | - | |
103 | -/* Name hashing routines. Initial hash value */ | |
104 | -/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ | |
105 | -#define init_name_hash() 0 | |
106 | - | |
107 | -/* partial hash update function. Assume roughly 4 bits per character */ | |
108 | -static inline unsigned long | |
109 | -partial_name_hash(unsigned long c, unsigned long prevhash) | |
110 | -{ | |
111 | - return (prevhash + (c << 4) + (c >> 4)) * 11; | |
112 | -} | |
113 | - | |
114 | -/* | |
115 | - * Finally: cut down the number of bits to a int value (and try to avoid | |
116 | - * losing bits) | |
117 | - */ | |
118 | -static inline unsigned long end_name_hash(unsigned long hash) | |
119 | -{ | |
120 | - return (unsigned int) hash; | |
121 | -} | |
122 | - | |
123 | -/* Compute the hash for a name string. */ | |
124 | -static inline unsigned int | |
125 | -full_name_hash(const unsigned char *name, unsigned int len) | |
126 | -{ | |
127 | - unsigned long hash = init_name_hash(); | |
128 | - while (len--) | |
129 | - hash = partial_name_hash(*name++, hash); | |
130 | - return end_name_hash(hash); | |
131 | -} | |
132 | - | |
133 | -#endif /* jffs2_private.h */ |