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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [jffs/] [jffs_fm.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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