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