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