OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [jffs/] [jffs_fm.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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.1.1.1 2004-04-15 01:09:59 phoenix 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 *
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
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
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
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
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
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
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 *
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
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
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 *
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
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 *
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
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
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
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
 
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
 
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
 
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
 
733
void jffs_free_node(struct jffs_node *n)
734
{
735
        kmem_cache_free(node_cache,n);
736
        no_jffs_node--;
737
}
738
 
739
 
740
int jffs_get_node_inuse(void)
741
{
742
        return no_jffs_node;
743
}
744
 
745
void
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
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
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.