1 /*
2 * JFFS -- Journaling Flash File System, Linux implementation.
3 *
4 * Copyright (C) 1999, 2000 Axis Communications AB.
5 *
6 * Created by Finn Hakansson <finn@axis.com>.
7 *
8 * This is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * $Id: jffs_fm.c,v 1.27 2001/09/20 12:29:47 dwmw2 Exp $
14 *
15 * Ported to Linux 2.3.x and MTD:
16 * Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
17 *
18 */
19 #define __NO_VERSION__
20 #include <linux/slab.h>
21 #include <linux/blkdev.h>
22 #include <linux/jffs.h>
23 #include "jffs_fm.h"
24
25 #if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
26 static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset);
27 #endif
28
29 extern kmem_cache_t *fm_cache;
30 extern kmem_cache_t *node_cache;
31
32 /* This function creates a new shiny flash memory control structure. */
33 struct jffs_fmcontrol *
jffs_build_begin(struct jffs_control * c,kdev_t dev)34 jffs_build_begin(struct jffs_control *c, kdev_t dev)
35 {
36 struct jffs_fmcontrol *fmc;
37 struct mtd_info *mtd;
38
39 D3(printk("jffs_build_begin()\n"));
40 fmc = (struct jffs_fmcontrol *)kmalloc(sizeof(struct jffs_fmcontrol),
41 GFP_KERNEL);
42 if (!fmc) {
43 D(printk("jffs_build_begin(): Allocation of "
44 "struct jffs_fmcontrol failed!\n"));
45 return (struct jffs_fmcontrol *)0;
46 }
47 DJM(no_jffs_fmcontrol++);
48
49 mtd = get_mtd_device(NULL, MINOR(dev));
50
51 if (!mtd) {
52 kfree(fmc);
53 DJM(no_jffs_fmcontrol--);
54 return NULL;
55 }
56
57 /* Retrieve the size of the flash memory. */
58 fmc->flash_size = mtd->size;
59 D3(printk(" fmc->flash_size = %d bytes\n", fmc->flash_size));
60
61 fmc->used_size = 0;
62 fmc->dirty_size = 0;
63 fmc->free_size = mtd->size;
64 fmc->sector_size = mtd->erasesize;
65 fmc->max_chunk_size = fmc->sector_size >> 1;
66 /* min_free_size:
67 1 sector, obviously.
68 + 1 x max_chunk_size, for when a nodes overlaps the end of a sector
69 + 1 x max_chunk_size again, which ought to be enough to handle
70 the case where a rename causes a name to grow, and GC has
71 to write out larger nodes than the ones it's obsoleting.
72 We should fix it so it doesn't have to write the name
73 _every_ time. Later.
74 + another 2 sectors because people keep getting GC stuck and
75 we don't know why. This scares me - I want formal proof
76 of correctness of whatever number we put here. dwmw2.
77 */
78 fmc->min_free_size = fmc->sector_size << 2;
79 fmc->mtd = mtd;
80 fmc->c = c;
81 fmc->head = 0;
82 fmc->tail = 0;
83 fmc->head_extra = 0;
84 fmc->tail_extra = 0;
85 init_MUTEX(&fmc->biglock);
86 return fmc;
87 }
88
89
90 /* When the flash memory scan has completed, this function should be called
91 before use of the control structure. */
92 void
jffs_build_end(struct jffs_fmcontrol * fmc)93 jffs_build_end(struct jffs_fmcontrol *fmc)
94 {
95 D3(printk("jffs_build_end()\n"));
96
97 if (!fmc->head) {
98 fmc->head = fmc->head_extra;
99 fmc->tail = fmc->tail_extra;
100 }
101 else if (fmc->head_extra) {
102 fmc->tail_extra->next = fmc->head;
103 fmc->head->prev = fmc->tail_extra;
104 fmc->head = fmc->head_extra;
105 }
106 fmc->head_extra = 0; /* These two instructions should be omitted. */
107 fmc->tail_extra = 0;
108 D3(jffs_print_fmcontrol(fmc));
109 }
110
111
112 /* Call this function when the file system is unmounted. This function
113 frees all memory used by this module. */
114 void
jffs_cleanup_fmcontrol(struct jffs_fmcontrol * fmc)115 jffs_cleanup_fmcontrol(struct jffs_fmcontrol *fmc)
116 {
117 if (fmc) {
118 struct jffs_fm *cur;
119 struct jffs_fm *next = fmc->head;
120
121 while ((cur = next)) {
122 next = next->next;
123 jffs_free_fm(cur);
124 }
125 put_mtd_device(fmc->mtd);
126 kfree(fmc);
127 DJM(no_jffs_fmcontrol--);
128 }
129 }
130
131
132 /* This function returns the size of the first chunk of free space on the
133 flash memory. This function will return something nonzero if the flash
134 memory contains any free space. */
135 __u32
jffs_free_size1(struct jffs_fmcontrol * fmc)136 jffs_free_size1(struct jffs_fmcontrol *fmc)
137 {
138 __u32 head;
139 __u32 tail;
140 __u32 end = fmc->flash_size;
141
142 if (!fmc->head) {
143 /* There is nothing on the flash. */
144 return fmc->flash_size;
145 }
146
147 /* Compute the beginning and ending of the contents of the flash. */
148 head = fmc->head->offset;
149 tail = fmc->tail->offset + fmc->tail->size;
150 if (tail == end) {
151 tail = 0;
152 }
153 ASSERT(else if (tail > end) {
154 printk(KERN_WARNING "jffs_free_size1(): tail > end\n");
155 tail = 0;
156 });
157
158 if (head <= tail) {
159 return end - tail;
160 }
161 else {
162 return head - tail;
163 }
164 }
165
166 /* This function will return something nonzero in case there are two free
167 areas on the flash. Like this:
168
169 +----------------+------------------+----------------+
170 | FREE 1 | USED / DIRTY | FREE 2 |
171 +----------------+------------------+----------------+
172 fmc->head -----^
173 fmc->tail ------------------------^
174
175 The value returned, will be the size of the first empty area on the
176 flash, in this case marked "FREE 1". */
177 __u32
jffs_free_size2(struct jffs_fmcontrol * fmc)178 jffs_free_size2(struct jffs_fmcontrol *fmc)
179 {
180 if (fmc->head) {
181 __u32 head = fmc->head->offset;
182 __u32 tail = fmc->tail->offset + fmc->tail->size;
183 if (tail == fmc->flash_size) {
184 tail = 0;
185 }
186
187 if (tail >= head) {
188 return head;
189 }
190 }
191 return 0;
192 }
193
194
195 /* Allocate a chunk of flash memory. If there is enough space on the
196 device, a reference to the associated node is stored in the jffs_fm
197 struct. */
198 int
jffs_fmalloc(struct jffs_fmcontrol * fmc,__u32 size,struct jffs_node * node,struct jffs_fm ** result)199 jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
200 struct jffs_fm **result)
201 {
202 struct jffs_fm *fm;
203 __u32 free_chunk_size1;
204 __u32 free_chunk_size2;
205
206 D2(printk("jffs_fmalloc(): fmc = 0x%p, size = %d, "
207 "node = 0x%p\n", fmc, size, node));
208
209 *result = 0;
210
211 if (!(fm = jffs_alloc_fm())) {
212 D(printk("jffs_fmalloc(): kmalloc() failed! (fm)\n"));
213 return -ENOMEM;
214 }
215
216 free_chunk_size1 = jffs_free_size1(fmc);
217 free_chunk_size2 = jffs_free_size2(fmc);
218 if (free_chunk_size1 + free_chunk_size2 != fmc->free_size) {
219 printk(KERN_WARNING "Free size accounting screwed\n");
220 printk(KERN_WARNING "free_chunk_size1 == 0x%x, free_chunk_size2 == 0x%x, fmc->free_size == 0x%x\n", free_chunk_size1, free_chunk_size2, fmc->free_size);
221 }
222
223 D3(printk("jffs_fmalloc(): free_chunk_size1 = %u, "
224 "free_chunk_size2 = %u\n",
225 free_chunk_size1, free_chunk_size2));
226
227 if (size <= free_chunk_size1) {
228 if (!(fm->nodes = (struct jffs_node_ref *)
229 kmalloc(sizeof(struct jffs_node_ref),
230 GFP_KERNEL))) {
231 D(printk("jffs_fmalloc(): kmalloc() failed! "
232 "(node_ref)\n"));
233 jffs_free_fm(fm);
234 return -ENOMEM;
235 }
236 DJM(no_jffs_node_ref++);
237 fm->nodes->node = node;
238 fm->nodes->next = 0;
239 if (fmc->tail) {
240 fm->offset = fmc->tail->offset + fmc->tail->size;
241 if (fm->offset == fmc->flash_size) {
242 fm->offset = 0;
243 }
244 ASSERT(else if (fm->offset > fmc->flash_size) {
245 printk(KERN_WARNING "jffs_fmalloc(): "
246 "offset > flash_end\n");
247 fm->offset = 0;
248 });
249 }
250 else {
251 /* There don't have to be files in the file
252 system yet. */
253 fm->offset = 0;
254 }
255 fm->size = size;
256 fmc->free_size -= size;
257 fmc->used_size += size;
258 }
259 else if (size > free_chunk_size2) {
260 printk(KERN_WARNING "JFFS: Tried to allocate a too "
261 "large flash memory chunk. (size = %u)\n", size);
262 jffs_free_fm(fm);
263 return -ENOSPC;
264 }
265 else {
266 fm->offset = fmc->tail->offset + fmc->tail->size;
267 fm->size = free_chunk_size1;
268 fm->nodes = 0;
269 fmc->free_size -= fm->size;
270 fmc->dirty_size += fm->size; /* Changed by simonk. This seemingly fixes a
271 bug that caused infinite garbage collection.
272 It previously set fmc->dirty_size to size (which is the
273 size of the requested chunk).
274 */
275 }
276
277 fm->next = 0;
278 if (!fmc->head) {
279 fm->prev = 0;
280 fmc->head = fm;
281 fmc->tail = fm;
282 }
283 else {
284 fm->prev = fmc->tail;
285 fmc->tail->next = fm;
286 fmc->tail = fm;
287 }
288
289 D3(jffs_print_fmcontrol(fmc));
290 D3(jffs_print_fm(fm));
291 *result = fm;
292 return 0;
293 }
294
295
296 /* The on-flash space is not needed anymore by the passed node. Remove
297 the reference to the node from the node list. If the data chunk in
298 the flash memory isn't used by any more nodes anymore (fm->nodes == 0),
299 then mark that chunk as dirty. */
300 int
jffs_fmfree(struct jffs_fmcontrol * fmc,struct jffs_fm * fm,struct jffs_node * node)301 jffs_fmfree(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, struct jffs_node *node)
302 {
303 struct jffs_node_ref *ref;
304 struct jffs_node_ref *prev;
305 ASSERT(int del = 0);
306
307 D2(printk("jffs_fmfree(): node->ino = %u, node->version = %u\n",
308 node->ino, node->version));
309
310 ASSERT(if (!fmc || !fm || !fm->nodes) {
311 printk(KERN_ERR "jffs_fmfree(): fmc: 0x%p, fm: 0x%p, "
312 "fm->nodes: 0x%p\n",
313 fmc, fm, (fm ? fm->nodes : 0));
314 return -1;
315 });
316
317 /* Find the reference to the node that is going to be removed
318 and remove it. */
319 for (ref = fm->nodes, prev = 0; ref; ref = ref->next) {
320 if (ref->node == node) {
321 if (prev) {
322 prev->next = ref->next;
323 }
324 else {
325 fm->nodes = ref->next;
326 }
327 kfree(ref);
328 DJM(no_jffs_node_ref--);
329 ASSERT(del = 1);
330 break;
331 }
332 prev = ref;
333 }
334
335 /* If the data chunk in the flash memory isn't used anymore
336 just mark it as obsolete. */
337 if (!fm->nodes) {
338 /* No node uses this chunk so let's remove it. */
339 fmc->used_size -= fm->size;
340 fmc->dirty_size += fm->size;
341 #if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
342 if (jffs_mark_obsolete(fmc, fm->offset) < 0) {
343 D1(printk("jffs_fmfree(): Failed to mark an on-flash "
344 "node obsolete!\n"));
345 return -1;
346 }
347 #endif
348 }
349
350 ASSERT(if (!del) {
351 printk(KERN_WARNING "***jffs_fmfree(): "
352 "Didn't delete any node reference!\n");
353 });
354
355 return 0;
356 }
357
358
359 /* This allocation function is used during the initialization of
360 the file system. */
361 struct jffs_fm *
jffs_fmalloced(struct jffs_fmcontrol * fmc,__u32 offset,__u32 size,struct jffs_node * node)362 jffs_fmalloced(struct jffs_fmcontrol *fmc, __u32 offset, __u32 size,
363 struct jffs_node *node)
364 {
365 struct jffs_fm *fm;
366
367 D3(printk("jffs_fmalloced()\n"));
368
369 if (!(fm = jffs_alloc_fm())) {
370 D(printk("jffs_fmalloced(0x%p, %u, %u, 0x%p): failed!\n",
371 fmc, offset, size, node));
372 return 0;
373 }
374 fm->offset = offset;
375 fm->size = size;
376 fm->prev = 0;
377 fm->next = 0;
378 fm->nodes = 0;
379 if (node) {
380 /* `node' exists and it should be associated with the
381 jffs_fm structure `fm'. */
382 if (!(fm->nodes = (struct jffs_node_ref *)
383 kmalloc(sizeof(struct jffs_node_ref),
384 GFP_KERNEL))) {
385 D(printk("jffs_fmalloced(): !fm->nodes\n"));
386 jffs_free_fm(fm);
387 return 0;
388 }
389 DJM(no_jffs_node_ref++);
390 fm->nodes->node = node;
391 fm->nodes->next = 0;
392 fmc->used_size += size;
393 fmc->free_size -= size;
394 }
395 else {
396 /* If there is no node, then this is just a chunk of dirt. */
397 fmc->dirty_size += size;
398 fmc->free_size -= size;
399 }
400
401 if (fmc->head_extra) {
402 fm->prev = fmc->tail_extra;
403 fmc->tail_extra->next = fm;
404 fmc->tail_extra = fm;
405 }
406 else if (!fmc->head) {
407 fmc->head = fm;
408 fmc->tail = fm;
409 }
410 else if (fmc->tail->offset + fmc->tail->size < offset) {
411 fmc->head_extra = fm;
412 fmc->tail_extra = fm;
413 }
414 else {
415 fm->prev = fmc->tail;
416 fmc->tail->next = fm;
417 fmc->tail = fm;
418 }
419 D3(jffs_print_fmcontrol(fmc));
420 D3(jffs_print_fm(fm));
421 return fm;
422 }
423
424
425 /* Add a new node to an already existing jffs_fm struct. */
426 int
jffs_add_node(struct jffs_node * node)427 jffs_add_node(struct jffs_node *node)
428 {
429 struct jffs_node_ref *ref;
430
431 D3(printk("jffs_add_node(): ino = %u\n", node->ino));
432
433 ref = (struct jffs_node_ref *)kmalloc(sizeof(struct jffs_node_ref),
434 GFP_KERNEL);
435 if (!ref)
436 return -ENOMEM;
437
438 DJM(no_jffs_node_ref++);
439 ref->node = node;
440 ref->next = node->fm->nodes;
441 node->fm->nodes = ref;
442 return 0;
443 }
444
445
446 /* Free a part of some allocated space. */
447 void
jffs_fmfree_partly(struct jffs_fmcontrol * fmc,struct jffs_fm * fm,__u32 size)448 jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, __u32 size)
449 {
450 D1(printk("***jffs_fmfree_partly(): fm = 0x%p, fm->nodes = 0x%p, "
451 "fm->nodes->node->ino = %u, size = %u\n",
452 fm, (fm ? fm->nodes : 0),
453 (!fm ? 0 : (!fm->nodes ? 0 : fm->nodes->node->ino)), size));
454
455 if (fm->nodes) {
456 kfree(fm->nodes);
457 DJM(no_jffs_node_ref--);
458 fm->nodes = 0;
459 }
460 fmc->used_size -= fm->size;
461 if (fm == fmc->tail) {
462 fm->size -= size;
463 fmc->free_size += size;
464 }
465 fmc->dirty_size += fm->size;
466 }
467
468
469 /* Find the jffs_fm struct that contains the end of the data chunk that
470 begins at the logical beginning of the flash memory and spans `size'
471 bytes. If we want to erase a sector of the flash memory, we use this
472 function to find where the sector limit cuts a chunk of data. */
473 struct jffs_fm *
jffs_cut_node(struct jffs_fmcontrol * fmc,__u32 size)474 jffs_cut_node(struct jffs_fmcontrol *fmc, __u32 size)
475 {
476 struct jffs_fm *fm;
477 __u32 pos = 0;
478
479 if (size == 0) {
480 return 0;
481 }
482
483 ASSERT(if (!fmc) {
484 printk(KERN_ERR "jffs_cut_node(): fmc == NULL\n");
485 return 0;
486 });
487
488 fm = fmc->head;
489
490 while (fm) {
491 pos += fm->size;
492 if (pos < size) {
493 fm = fm->next;
494 }
495 else if (pos > size) {
496 break;
497 }
498 else {
499 fm = 0;
500 break;
501 }
502 }
503
504 return fm;
505 }
506
507
508 /* Move the head of the fmc structures and delete the obsolete parts. */
509 void
jffs_sync_erase(struct jffs_fmcontrol * fmc,int erased_size)510 jffs_sync_erase(struct jffs_fmcontrol *fmc, int erased_size)
511 {
512 struct jffs_fm *fm;
513 struct jffs_fm *del;
514
515 ASSERT(if (!fmc) {
516 printk(KERN_ERR "jffs_sync_erase(): fmc == NULL\n");
517 return;
518 });
519
520 fmc->dirty_size -= erased_size;
521 fmc->free_size += erased_size;
522
523 for (fm = fmc->head; fm && (erased_size > 0);) {
524 if (erased_size >= fm->size) {
525 erased_size -= fm->size;
526 del = fm;
527 fm = fm->next;
528 fm->prev = 0;
529 fmc->head = fm;
530 jffs_free_fm(del);
531 }
532 else {
533 fm->size -= erased_size;
534 fm->offset += erased_size;
535 break;
536 }
537 }
538 }
539
540
541 /* Return the oldest used node in the flash memory. */
542 struct jffs_node *
jffs_get_oldest_node(struct jffs_fmcontrol * fmc)543 jffs_get_oldest_node(struct jffs_fmcontrol *fmc)
544 {
545 struct jffs_fm *fm;
546 struct jffs_node_ref *nref;
547 struct jffs_node *node = 0;
548
549 ASSERT(if (!fmc) {
550 printk(KERN_ERR "jffs_get_oldest_node(): fmc == NULL\n");
551 return 0;
552 });
553
554 for (fm = fmc->head; fm && !fm->nodes; fm = fm->next);
555
556 if (!fm) {
557 return 0;
558 }
559
560 /* The oldest node is the last one in the reference list. This list
561 shouldn't be too long; just one or perhaps two elements. */
562 for (nref = fm->nodes; nref; nref = nref->next) {
563 node = nref->node;
564 }
565
566 D2(printk("jffs_get_oldest_node(): ino = %u, version = %u\n",
567 (node ? node->ino : 0), (node ? node->version : 0)));
568
569 return node;
570 }
571
572
573 #if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
574
575 /* Mark an on-flash node as obsolete.
576
577 Note that this is just an optimization that isn't necessary for the
578 filesystem to work. */
579
580 static int
jffs_mark_obsolete(struct jffs_fmcontrol * fmc,__u32 fm_offset)581 jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset)
582 {
583 /* The `accurate_pos' holds the position of the accurate byte
584 in the jffs_raw_inode structure that we are going to mark
585 as obsolete. */
586 __u32 accurate_pos = fm_offset + JFFS_RAW_INODE_ACCURATE_OFFSET;
587 unsigned char zero = 0x00;
588 size_t len;
589
590 D3(printk("jffs_mark_obsolete(): accurate_pos = %u\n", accurate_pos));
591 ASSERT(if (!fmc) {
592 printk(KERN_ERR "jffs_mark_obsolete(): fmc == NULL\n");
593 return -1;
594 });
595
596 /* Write 0x00 to the raw inode's accurate member. Don't care
597 about the return value. */
598 MTD_WRITE(fmc->mtd, accurate_pos, 1, &len, &zero);
599 return 0;
600 }
601
602 #endif /* JFFS_MARK_OBSOLETE */
603
604 /* check if it's possible to erase the wanted range, and if not, return
605 * the range that IS erasable, or a negative error code.
606 */
607 long
jffs_flash_erasable_size(struct mtd_info * mtd,__u32 offset,__u32 size)608 jffs_flash_erasable_size(struct mtd_info *mtd, __u32 offset, __u32 size)
609 {
610 u_long ssize;
611
612 /* assume that sector size for a partition is constant even
613 * if it spans more than one chip (you usually put the same
614 * type of chips in a system)
615 */
616
617 ssize = mtd->erasesize;
618
619 if (offset % ssize) {
620 printk(KERN_WARNING "jffs_flash_erasable_size() given non-aligned offset %x (erasesize %lx)\n", offset, ssize);
621 /* The offset is not sector size aligned. */
622 return -1;
623 }
624 else if (offset > mtd->size) {
625 printk(KERN_WARNING "jffs_flash_erasable_size given offset off the end of device (%x > %x)\n", offset, mtd->size);
626 return -2;
627 }
628 else if (offset + size > mtd->size) {
629 printk(KERN_WARNING "jffs_flash_erasable_size() given length which runs off the end of device (ofs %x + len %x = %x, > %x)\n", offset,size, offset+size, mtd->size);
630 return -3;
631 }
632
633 return (size / ssize) * ssize;
634 }
635
636
637 /* How much dirty flash memory is possible to erase at the moment? */
638 long
jffs_erasable_size(struct jffs_fmcontrol * fmc)639 jffs_erasable_size(struct jffs_fmcontrol *fmc)
640 {
641 struct jffs_fm *fm;
642 __u32 size = 0;
643 long ret;
644
645 ASSERT(if (!fmc) {
646 printk(KERN_ERR "jffs_erasable_size(): fmc = NULL\n");
647 return -1;
648 });
649
650 if (!fmc->head) {
651 /* The flash memory is totally empty. No nodes. No dirt.
652 Just return. */
653 return 0;
654 }
655
656 /* Calculate how much space that is dirty. */
657 for (fm = fmc->head; fm && !fm->nodes; fm = fm->next) {
658 if (size && fm->offset == 0) {
659 /* We have reached the beginning of the flash. */
660 break;
661 }
662 size += fm->size;
663 }
664
665 /* Someone's signature contained this:
666 There's a fine line between fishing and just standing on
667 the shore like an idiot... */
668 ret = jffs_flash_erasable_size(fmc->mtd, fmc->head->offset, size);
669
670 ASSERT(if (ret < 0) {
671 printk("jffs_erasable_size: flash_erasable_size() "
672 "returned something less than zero (%ld).\n", ret);
673 printk("jffs_erasable_size: offset = 0x%08x\n",
674 fmc->head->offset);
675 });
676
677 /* If there is dirt on the flash (which is the reason to why
678 this function was called in the first place) but no space is
679 possible to erase right now, the initial part of the list of
680 jffs_fm structs, that hold place for dirty space, could perhaps
681 be shortened. The list's initial "dirty" elements are merged
682 into just one large dirty jffs_fm struct. This operation must
683 only be performed if nothing is possible to erase. Otherwise,
684 jffs_clear_end_of_node() won't work as expected. */
685 if (ret == 0) {
686 struct jffs_fm *head = fmc->head;
687 struct jffs_fm *del;
688 /* While there are two dirty nodes beside each other.*/
689 while (head->nodes == 0
690 && head->next
691 && head->next->nodes == 0) {
692 del = head->next;
693 head->size += del->size;
694 head->next = del->next;
695 if (del->next) {
696 del->next->prev = head;
697 }
698 jffs_free_fm(del);
699 }
700 }
701
702 return (ret >= 0 ? ret : 0);
703 }
704
jffs_alloc_fm(void)705 struct jffs_fm *jffs_alloc_fm(void)
706 {
707 struct jffs_fm *fm;
708
709 fm = kmem_cache_alloc(fm_cache,GFP_KERNEL);
710 DJM(if (fm) no_jffs_fm++;);
711
712 return fm;
713 }
714
jffs_free_fm(struct jffs_fm * n)715 void jffs_free_fm(struct jffs_fm *n)
716 {
717 kmem_cache_free(fm_cache,n);
718 DJM(no_jffs_fm--);
719 }
720
721
722
jffs_alloc_node(void)723 struct jffs_node *jffs_alloc_node(void)
724 {
725 struct jffs_node *n;
726
727 n = (struct jffs_node *)kmem_cache_alloc(node_cache,GFP_KERNEL);
728 if(n != NULL)
729 no_jffs_node++;
730 return n;
731 }
732
jffs_free_node(struct jffs_node * n)733 void jffs_free_node(struct jffs_node *n)
734 {
735 kmem_cache_free(node_cache,n);
736 no_jffs_node--;
737 }
738
739
jffs_get_node_inuse(void)740 int jffs_get_node_inuse(void)
741 {
742 return no_jffs_node;
743 }
744
745 void
jffs_print_fmcontrol(struct jffs_fmcontrol * fmc)746 jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
747 {
748 D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
749 D(printk("{\n"));
750 D(printk(" %u, /* flash_size */\n", fmc->flash_size));
751 D(printk(" %u, /* used_size */\n", fmc->used_size));
752 D(printk(" %u, /* dirty_size */\n", fmc->dirty_size));
753 D(printk(" %u, /* free_size */\n", fmc->free_size));
754 D(printk(" %u, /* sector_size */\n", fmc->sector_size));
755 D(printk(" %u, /* min_free_size */\n", fmc->min_free_size));
756 D(printk(" %u, /* max_chunk_size */\n", fmc->max_chunk_size));
757 D(printk(" 0x%p, /* mtd */\n", fmc->mtd));
758 D(printk(" 0x%p, /* head */ "
759 "(head->offset = 0x%08x)\n",
760 fmc->head, (fmc->head ? fmc->head->offset : 0)));
761 D(printk(" 0x%p, /* tail */ "
762 "(tail->offset + tail->size = 0x%08x)\n",
763 fmc->tail,
764 (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0)));
765 D(printk(" 0x%p, /* head_extra */\n", fmc->head_extra));
766 D(printk(" 0x%p, /* tail_extra */\n", fmc->tail_extra));
767 D(printk("}\n"));
768 }
769
770 void
jffs_print_fm(struct jffs_fm * fm)771 jffs_print_fm(struct jffs_fm *fm)
772 {
773 D(printk("struct jffs_fm: 0x%p\n", fm));
774 D(printk("{\n"));
775 D(printk(" 0x%08x, /* offset */\n", fm->offset));
776 D(printk(" %u, /* size */\n", fm->size));
777 D(printk(" 0x%p, /* prev */\n", fm->prev));
778 D(printk(" 0x%p, /* next */\n", fm->next));
779 D(printk(" 0x%p, /* nodes */\n", fm->nodes));
780 D(printk("}\n"));
781 }
782
783 void
jffs_print_node_ref(struct jffs_node_ref * ref)784 jffs_print_node_ref(struct jffs_node_ref *ref)
785 {
786 D(printk("struct jffs_node_ref: 0x%p\n", ref));
787 D(printk("{\n"));
788 D(printk(" 0x%p, /* node */\n", ref->node));
789 D(printk(" 0x%p, /* next */\n", ref->next));
790 D(printk("}\n"));
791 }
792