initial commit with v2.6.9
[linux-2.6.9-moxart.git] / fs / jffs / jffs_fm.c
blobfae439d48398ac54e4141da863cb9210d010b47e
1 /*
2 * JFFS -- Journaling Flash File System, Linux implementation.
4 * Copyright (C) 1999, 2000 Axis Communications AB.
6 * Created by Finn Hakansson <finn@axis.com>.
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.
13 * $Id: jffs_fm.c,v 1.27 2001/09/20 12:29:47 dwmw2 Exp $
15 * Ported to Linux 2.3.x and MTD:
16 * Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
19 #include <linux/slab.h>
20 #include <linux/blkdev.h>
21 #include <linux/jffs.h>
22 #include "jffs_fm.h"
24 #if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
25 static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset);
26 #endif
28 extern kmem_cache_t *fm_cache;
29 extern kmem_cache_t *node_cache;
31 /* This function creates a new shiny flash memory control structure. */
32 struct jffs_fmcontrol *
33 jffs_build_begin(struct jffs_control *c, int unit)
35 struct jffs_fmcontrol *fmc;
36 struct mtd_info *mtd;
38 D3(printk("jffs_build_begin()\n"));
39 fmc = (struct jffs_fmcontrol *)kmalloc(sizeof(struct jffs_fmcontrol),
40 GFP_KERNEL);
41 if (!fmc) {
42 D(printk("jffs_build_begin(): Allocation of "
43 "struct jffs_fmcontrol failed!\n"));
44 return (struct jffs_fmcontrol *)0;
46 DJM(no_jffs_fmcontrol++);
48 mtd = get_mtd_device(NULL, unit);
50 if (!mtd) {
51 kfree(fmc);
52 DJM(no_jffs_fmcontrol--);
53 return NULL;
56 /* Retrieve the size of the flash memory. */
57 fmc->flash_size = mtd->size;
58 D3(printk(" fmc->flash_size = %d bytes\n", fmc->flash_size));
60 fmc->used_size = 0;
61 fmc->dirty_size = 0;
62 fmc->free_size = mtd->size;
63 fmc->sector_size = mtd->erasesize;
64 fmc->max_chunk_size = fmc->sector_size >> 1;
65 /* min_free_size:
66 1 sector, obviously.
67 + 1 x max_chunk_size, for when a nodes overlaps the end of a sector
68 + 1 x max_chunk_size again, which ought to be enough to handle
69 the case where a rename causes a name to grow, and GC has
70 to write out larger nodes than the ones it's obsoleting.
71 We should fix it so it doesn't have to write the name
72 _every_ time. Later.
73 + another 2 sectors because people keep getting GC stuck and
74 we don't know why. This scares me - I want formal proof
75 of correctness of whatever number we put here. dwmw2.
77 fmc->min_free_size = fmc->sector_size << 2;
78 fmc->mtd = mtd;
79 fmc->c = c;
80 fmc->head = NULL;
81 fmc->tail = NULL;
82 fmc->head_extra = NULL;
83 fmc->tail_extra = NULL;
84 init_MUTEX(&fmc->biglock);
85 return fmc;
89 /* When the flash memory scan has completed, this function should be called
90 before use of the control structure. */
91 void
92 jffs_build_end(struct jffs_fmcontrol *fmc)
94 D3(printk("jffs_build_end()\n"));
96 if (!fmc->head) {
97 fmc->head = fmc->head_extra;
98 fmc->tail = fmc->tail_extra;
100 else if (fmc->head_extra) {
101 fmc->tail_extra->next = fmc->head;
102 fmc->head->prev = fmc->tail_extra;
103 fmc->head = fmc->head_extra;
105 fmc->head_extra = NULL; /* These two instructions should be omitted. */
106 fmc->tail_extra = NULL;
107 D3(jffs_print_fmcontrol(fmc));
111 /* Call this function when the file system is unmounted. This function
112 frees all memory used by this module. */
113 void
114 jffs_cleanup_fmcontrol(struct jffs_fmcontrol *fmc)
116 if (fmc) {
117 struct jffs_fm *next = fmc->head;
118 while (next) {
119 struct jffs_fm *cur = next;
120 next = next->next;
121 jffs_free_fm(cur);
123 put_mtd_device(fmc->mtd);
124 kfree(fmc);
125 DJM(no_jffs_fmcontrol--);
130 /* This function returns the size of the first chunk of free space on the
131 flash memory. This function will return something nonzero if the flash
132 memory contains any free space. */
133 __u32
134 jffs_free_size1(struct jffs_fmcontrol *fmc)
136 __u32 head;
137 __u32 tail;
138 __u32 end = fmc->flash_size;
140 if (!fmc->head) {
141 /* There is nothing on the flash. */
142 return fmc->flash_size;
145 /* Compute the beginning and ending of the contents of the flash. */
146 head = fmc->head->offset;
147 tail = fmc->tail->offset + fmc->tail->size;
148 if (tail == end) {
149 tail = 0;
151 ASSERT(else if (tail > end) {
152 printk(KERN_WARNING "jffs_free_size1(): tail > end\n");
153 tail = 0;
156 if (head <= tail) {
157 return end - tail;
159 else {
160 return head - tail;
164 /* This function will return something nonzero in case there are two free
165 areas on the flash. Like this:
167 +----------------+------------------+----------------+
168 | FREE 1 | USED / DIRTY | FREE 2 |
169 +----------------+------------------+----------------+
170 fmc->head -----^
171 fmc->tail ------------------------^
173 The value returned, will be the size of the first empty area on the
174 flash, in this case marked "FREE 1". */
175 __u32
176 jffs_free_size2(struct jffs_fmcontrol *fmc)
178 if (fmc->head) {
179 __u32 head = fmc->head->offset;
180 __u32 tail = fmc->tail->offset + fmc->tail->size;
181 if (tail == fmc->flash_size) {
182 tail = 0;
185 if (tail >= head) {
186 return head;
189 return 0;
193 /* Allocate a chunk of flash memory. If there is enough space on the
194 device, a reference to the associated node is stored in the jffs_fm
195 struct. */
197 jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
198 struct jffs_fm **result)
200 struct jffs_fm *fm;
201 __u32 free_chunk_size1;
202 __u32 free_chunk_size2;
204 D2(printk("jffs_fmalloc(): fmc = 0x%p, size = %d, "
205 "node = 0x%p\n", fmc, size, node));
207 *result = NULL;
209 if (!(fm = jffs_alloc_fm())) {
210 D(printk("jffs_fmalloc(): kmalloc() failed! (fm)\n"));
211 return -ENOMEM;
214 free_chunk_size1 = jffs_free_size1(fmc);
215 free_chunk_size2 = jffs_free_size2(fmc);
216 if (free_chunk_size1 + free_chunk_size2 != fmc->free_size) {
217 printk(KERN_WARNING "Free size accounting screwed\n");
218 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 D3(printk("jffs_fmalloc(): free_chunk_size1 = %u, "
222 "free_chunk_size2 = %u\n",
223 free_chunk_size1, free_chunk_size2));
225 if (size <= free_chunk_size1) {
226 if (!(fm->nodes = (struct jffs_node_ref *)
227 kmalloc(sizeof(struct jffs_node_ref),
228 GFP_KERNEL))) {
229 D(printk("jffs_fmalloc(): kmalloc() failed! "
230 "(node_ref)\n"));
231 jffs_free_fm(fm);
232 return -ENOMEM;
234 DJM(no_jffs_node_ref++);
235 fm->nodes->node = node;
236 fm->nodes->next = NULL;
237 if (fmc->tail) {
238 fm->offset = fmc->tail->offset + fmc->tail->size;
239 if (fm->offset == fmc->flash_size) {
240 fm->offset = 0;
242 ASSERT(else if (fm->offset > fmc->flash_size) {
243 printk(KERN_WARNING "jffs_fmalloc(): "
244 "offset > flash_end\n");
245 fm->offset = 0;
248 else {
249 /* There don't have to be files in the file
250 system yet. */
251 fm->offset = 0;
253 fm->size = size;
254 fmc->free_size -= size;
255 fmc->used_size += size;
257 else if (size > free_chunk_size2) {
258 printk(KERN_WARNING "JFFS: Tried to allocate a too "
259 "large flash memory chunk. (size = %u)\n", size);
260 jffs_free_fm(fm);
261 return -ENOSPC;
263 else {
264 fm->offset = fmc->tail->offset + fmc->tail->size;
265 fm->size = free_chunk_size1;
266 fm->nodes = NULL;
267 fmc->free_size -= fm->size;
268 fmc->dirty_size += fm->size; /* Changed by simonk. This seemingly fixes a
269 bug that caused infinite garbage collection.
270 It previously set fmc->dirty_size to size (which is the
271 size of the requested chunk).
275 fm->next = NULL;
276 if (!fmc->head) {
277 fm->prev = NULL;
278 fmc->head = fm;
279 fmc->tail = fm;
281 else {
282 fm->prev = fmc->tail;
283 fmc->tail->next = fm;
284 fmc->tail = fm;
287 D3(jffs_print_fmcontrol(fmc));
288 D3(jffs_print_fm(fm));
289 *result = fm;
290 return 0;
294 /* The on-flash space is not needed anymore by the passed node. Remove
295 the reference to the node from the node list. If the data chunk in
296 the flash memory isn't used by any more nodes anymore (fm->nodes == 0),
297 then mark that chunk as dirty. */
299 jffs_fmfree(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, struct jffs_node *node)
301 struct jffs_node_ref *ref;
302 struct jffs_node_ref *prev;
303 ASSERT(int del = 0);
305 D2(printk("jffs_fmfree(): node->ino = %u, node->version = %u\n",
306 node->ino, node->version));
308 ASSERT(if (!fmc || !fm || !fm->nodes) {
309 printk(KERN_ERR "jffs_fmfree(): fmc: 0x%p, fm: 0x%p, "
310 "fm->nodes: 0x%p\n",
311 fmc, fm, (fm ? fm->nodes : NULL));
312 return -1;
315 /* Find the reference to the node that is going to be removed
316 and remove it. */
317 for (ref = fm->nodes, prev = NULL; ref; ref = ref->next) {
318 if (ref->node == node) {
319 if (prev) {
320 prev->next = ref->next;
322 else {
323 fm->nodes = ref->next;
325 kfree(ref);
326 DJM(no_jffs_node_ref--);
327 ASSERT(del = 1);
328 break;
330 prev = ref;
333 /* If the data chunk in the flash memory isn't used anymore
334 just mark it as obsolete. */
335 if (!fm->nodes) {
336 /* No node uses this chunk so let's remove it. */
337 fmc->used_size -= fm->size;
338 fmc->dirty_size += fm->size;
339 #if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
340 if (jffs_mark_obsolete(fmc, fm->offset) < 0) {
341 D1(printk("jffs_fmfree(): Failed to mark an on-flash "
342 "node obsolete!\n"));
343 return -1;
345 #endif
348 ASSERT(if (!del) {
349 printk(KERN_WARNING "***jffs_fmfree(): "
350 "Didn't delete any node reference!\n");
353 return 0;
357 /* This allocation function is used during the initialization of
358 the file system. */
359 struct jffs_fm *
360 jffs_fmalloced(struct jffs_fmcontrol *fmc, __u32 offset, __u32 size,
361 struct jffs_node *node)
363 struct jffs_fm *fm;
365 D3(printk("jffs_fmalloced()\n"));
367 if (!(fm = jffs_alloc_fm())) {
368 D(printk("jffs_fmalloced(0x%p, %u, %u, 0x%p): failed!\n",
369 fmc, offset, size, node));
370 return NULL;
372 fm->offset = offset;
373 fm->size = size;
374 fm->prev = NULL;
375 fm->next = NULL;
376 fm->nodes = NULL;
377 if (node) {
378 /* `node' exists and it should be associated with the
379 jffs_fm structure `fm'. */
380 if (!(fm->nodes = (struct jffs_node_ref *)
381 kmalloc(sizeof(struct jffs_node_ref),
382 GFP_KERNEL))) {
383 D(printk("jffs_fmalloced(): !fm->nodes\n"));
384 jffs_free_fm(fm);
385 return NULL;
387 DJM(no_jffs_node_ref++);
388 fm->nodes->node = node;
389 fm->nodes->next = NULL;
390 fmc->used_size += size;
391 fmc->free_size -= size;
393 else {
394 /* If there is no node, then this is just a chunk of dirt. */
395 fmc->dirty_size += size;
396 fmc->free_size -= size;
399 if (fmc->head_extra) {
400 fm->prev = fmc->tail_extra;
401 fmc->tail_extra->next = fm;
402 fmc->tail_extra = fm;
404 else if (!fmc->head) {
405 fmc->head = fm;
406 fmc->tail = fm;
408 else if (fmc->tail->offset + fmc->tail->size < offset) {
409 fmc->head_extra = fm;
410 fmc->tail_extra = fm;
412 else {
413 fm->prev = fmc->tail;
414 fmc->tail->next = fm;
415 fmc->tail = fm;
417 D3(jffs_print_fmcontrol(fmc));
418 D3(jffs_print_fm(fm));
419 return fm;
423 /* Add a new node to an already existing jffs_fm struct. */
425 jffs_add_node(struct jffs_node *node)
427 struct jffs_node_ref *ref;
429 D3(printk("jffs_add_node(): ino = %u\n", node->ino));
431 ref = (struct jffs_node_ref *)kmalloc(sizeof(struct jffs_node_ref),
432 GFP_KERNEL);
433 if (!ref)
434 return -ENOMEM;
436 DJM(no_jffs_node_ref++);
437 ref->node = node;
438 ref->next = node->fm->nodes;
439 node->fm->nodes = ref;
440 return 0;
444 /* Free a part of some allocated space. */
445 void
446 jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, __u32 size)
448 D1(printk("***jffs_fmfree_partly(): fm = 0x%p, fm->nodes = 0x%p, "
449 "fm->nodes->node->ino = %u, size = %u\n",
450 fm, (fm ? fm->nodes : 0),
451 (!fm ? 0 : (!fm->nodes ? 0 : fm->nodes->node->ino)), size));
453 if (fm->nodes) {
454 kfree(fm->nodes);
455 DJM(no_jffs_node_ref--);
456 fm->nodes = NULL;
458 fmc->used_size -= fm->size;
459 if (fm == fmc->tail) {
460 fm->size -= size;
461 fmc->free_size += size;
463 fmc->dirty_size += fm->size;
467 /* Find the jffs_fm struct that contains the end of the data chunk that
468 begins at the logical beginning of the flash memory and spans `size'
469 bytes. If we want to erase a sector of the flash memory, we use this
470 function to find where the sector limit cuts a chunk of data. */
471 struct jffs_fm *
472 jffs_cut_node(struct jffs_fmcontrol *fmc, __u32 size)
474 struct jffs_fm *fm;
475 __u32 pos = 0;
477 if (size == 0) {
478 return NULL;
481 ASSERT(if (!fmc) {
482 printk(KERN_ERR "jffs_cut_node(): fmc == NULL\n");
483 return NULL;
486 fm = fmc->head;
488 while (fm) {
489 pos += fm->size;
490 if (pos < size) {
491 fm = fm->next;
493 else if (pos > size) {
494 break;
496 else {
497 fm = NULL;
498 break;
502 return fm;
506 /* Move the head of the fmc structures and delete the obsolete parts. */
507 void
508 jffs_sync_erase(struct jffs_fmcontrol *fmc, int erased_size)
510 struct jffs_fm *fm;
511 struct jffs_fm *del;
513 ASSERT(if (!fmc) {
514 printk(KERN_ERR "jffs_sync_erase(): fmc == NULL\n");
515 return;
518 fmc->dirty_size -= erased_size;
519 fmc->free_size += erased_size;
521 for (fm = fmc->head; fm && (erased_size > 0);) {
522 if (erased_size >= fm->size) {
523 erased_size -= fm->size;
524 del = fm;
525 fm = fm->next;
526 fm->prev = NULL;
527 fmc->head = fm;
528 jffs_free_fm(del);
530 else {
531 fm->size -= erased_size;
532 fm->offset += erased_size;
533 break;
539 /* Return the oldest used node in the flash memory. */
540 struct jffs_node *
541 jffs_get_oldest_node(struct jffs_fmcontrol *fmc)
543 struct jffs_fm *fm;
544 struct jffs_node_ref *nref;
545 struct jffs_node *node = NULL;
547 ASSERT(if (!fmc) {
548 printk(KERN_ERR "jffs_get_oldest_node(): fmc == NULL\n");
549 return NULL;
552 for (fm = fmc->head; fm && !fm->nodes; fm = fm->next);
554 if (!fm) {
555 return NULL;
558 /* The oldest node is the last one in the reference list. This list
559 shouldn't be too long; just one or perhaps two elements. */
560 for (nref = fm->nodes; nref; nref = nref->next) {
561 node = nref->node;
564 D2(printk("jffs_get_oldest_node(): ino = %u, version = %u\n",
565 (node ? node->ino : 0), (node ? node->version : 0)));
567 return node;
571 #if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
573 /* Mark an on-flash node as obsolete.
575 Note that this is just an optimization that isn't necessary for the
576 filesystem to work. */
578 static int
579 jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset)
581 /* The `accurate_pos' holds the position of the accurate byte
582 in the jffs_raw_inode structure that we are going to mark
583 as obsolete. */
584 __u32 accurate_pos = fm_offset + JFFS_RAW_INODE_ACCURATE_OFFSET;
585 unsigned char zero = 0x00;
586 size_t len;
588 D3(printk("jffs_mark_obsolete(): accurate_pos = %u\n", accurate_pos));
589 ASSERT(if (!fmc) {
590 printk(KERN_ERR "jffs_mark_obsolete(): fmc == NULL\n");
591 return -1;
594 /* Write 0x00 to the raw inode's accurate member. Don't care
595 about the return value. */
596 MTD_WRITE(fmc->mtd, accurate_pos, 1, &len, &zero);
597 return 0;
600 #endif /* JFFS_MARK_OBSOLETE */
602 /* check if it's possible to erase the wanted range, and if not, return
603 * the range that IS erasable, or a negative error code.
605 long
606 jffs_flash_erasable_size(struct mtd_info *mtd, __u32 offset, __u32 size)
608 u_long ssize;
610 /* assume that sector size for a partition is constant even
611 * if it spans more than one chip (you usually put the same
612 * type of chips in a system)
615 ssize = mtd->erasesize;
617 if (offset % ssize) {
618 printk(KERN_WARNING "jffs_flash_erasable_size() given non-aligned offset %x (erasesize %lx)\n", offset, ssize);
619 /* The offset is not sector size aligned. */
620 return -1;
622 else if (offset > mtd->size) {
623 printk(KERN_WARNING "jffs_flash_erasable_size given offset off the end of device (%x > %x)\n", offset, mtd->size);
624 return -2;
626 else if (offset + size > mtd->size) {
627 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);
628 return -3;
631 return (size / ssize) * ssize;
635 /* How much dirty flash memory is possible to erase at the moment? */
636 long
637 jffs_erasable_size(struct jffs_fmcontrol *fmc)
639 struct jffs_fm *fm;
640 __u32 size = 0;
641 long ret;
643 ASSERT(if (!fmc) {
644 printk(KERN_ERR "jffs_erasable_size(): fmc = NULL\n");
645 return -1;
648 if (!fmc->head) {
649 /* The flash memory is totally empty. No nodes. No dirt.
650 Just return. */
651 return 0;
654 /* Calculate how much space that is dirty. */
655 for (fm = fmc->head; fm && !fm->nodes; fm = fm->next) {
656 if (size && fm->offset == 0) {
657 /* We have reached the beginning of the flash. */
658 break;
660 size += fm->size;
663 /* Someone's signature contained this:
664 There's a fine line between fishing and just standing on
665 the shore like an idiot... */
666 ret = jffs_flash_erasable_size(fmc->mtd, fmc->head->offset, size);
668 ASSERT(if (ret < 0) {
669 printk("jffs_erasable_size: flash_erasable_size() "
670 "returned something less than zero (%ld).\n", ret);
671 printk("jffs_erasable_size: offset = 0x%08x\n",
672 fmc->head->offset);
675 /* If there is dirt on the flash (which is the reason to why
676 this function was called in the first place) but no space is
677 possible to erase right now, the initial part of the list of
678 jffs_fm structs, that hold place for dirty space, could perhaps
679 be shortened. The list's initial "dirty" elements are merged
680 into just one large dirty jffs_fm struct. This operation must
681 only be performed if nothing is possible to erase. Otherwise,
682 jffs_clear_end_of_node() won't work as expected. */
683 if (ret == 0) {
684 struct jffs_fm *head = fmc->head;
685 struct jffs_fm *del;
686 /* While there are two dirty nodes beside each other.*/
687 while (head->nodes == 0
688 && head->next
689 && head->next->nodes == 0) {
690 del = head->next;
691 head->size += del->size;
692 head->next = del->next;
693 if (del->next) {
694 del->next->prev = head;
696 jffs_free_fm(del);
700 return (ret >= 0 ? ret : 0);
703 struct jffs_fm *jffs_alloc_fm(void)
705 struct jffs_fm *fm;
707 fm = kmem_cache_alloc(fm_cache,GFP_KERNEL);
708 DJM(if (fm) no_jffs_fm++;);
710 return fm;
713 void jffs_free_fm(struct jffs_fm *n)
715 kmem_cache_free(fm_cache,n);
716 DJM(no_jffs_fm--);
721 struct jffs_node *jffs_alloc_node(void)
723 struct jffs_node *n;
725 n = (struct jffs_node *)kmem_cache_alloc(node_cache,GFP_KERNEL);
726 if(n != NULL)
727 no_jffs_node++;
728 return n;
731 void jffs_free_node(struct jffs_node *n)
733 kmem_cache_free(node_cache,n);
734 no_jffs_node--;
738 int jffs_get_node_inuse(void)
740 return no_jffs_node;
743 void
744 jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
746 D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
747 D(printk("{\n"));
748 D(printk(" %u, /* flash_size */\n", fmc->flash_size));
749 D(printk(" %u, /* used_size */\n", fmc->used_size));
750 D(printk(" %u, /* dirty_size */\n", fmc->dirty_size));
751 D(printk(" %u, /* free_size */\n", fmc->free_size));
752 D(printk(" %u, /* sector_size */\n", fmc->sector_size));
753 D(printk(" %u, /* min_free_size */\n", fmc->min_free_size));
754 D(printk(" %u, /* max_chunk_size */\n", fmc->max_chunk_size));
755 D(printk(" 0x%p, /* mtd */\n", fmc->mtd));
756 D(printk(" 0x%p, /* head */ "
757 "(head->offset = 0x%08x)\n",
758 fmc->head, (fmc->head ? fmc->head->offset : 0)));
759 D(printk(" 0x%p, /* tail */ "
760 "(tail->offset + tail->size = 0x%08x)\n",
761 fmc->tail,
762 (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0)));
763 D(printk(" 0x%p, /* head_extra */\n", fmc->head_extra));
764 D(printk(" 0x%p, /* tail_extra */\n", fmc->tail_extra));
765 D(printk("}\n"));
768 void
769 jffs_print_fm(struct jffs_fm *fm)
771 D(printk("struct jffs_fm: 0x%p\n", fm));
772 D(printk("{\n"));
773 D(printk(" 0x%08x, /* offset */\n", fm->offset));
774 D(printk(" %u, /* size */\n", fm->size));
775 D(printk(" 0x%p, /* prev */\n", fm->prev));
776 D(printk(" 0x%p, /* next */\n", fm->next));
777 D(printk(" 0x%p, /* nodes */\n", fm->nodes));
778 D(printk("}\n"));
781 void
782 jffs_print_node_ref(struct jffs_node_ref *ref)
784 D(printk("struct jffs_node_ref: 0x%p\n", ref));
785 D(printk("{\n"));
786 D(printk(" 0x%p, /* node */\n", ref->node));
787 D(printk(" 0x%p, /* next */\n", ref->next));
788 D(printk("}\n"));