source: rtems/cpukit/libfs/src/jffs2/src/nodemgmt.c @ 6ac6a5c8

Last change on this file since 6ac6a5c8 was 6ac6a5c8, checked in by Sebastian Huber <sebastian.huber@…>, on Mar 27, 2018 at 11:01:56 AM

jffs2: Do not use command line defines

Update #3375.

  • Property mode set to 100644
File size: 28.4 KB
Line 
1#include "rtems-jffs2-config.h"
2
3/*
4 * JFFS2 -- Journalling Flash File System, Version 2.
5 *
6 * Copyright © 2001-2007 Red Hat, Inc.
7 *
8 * Created by David Woodhouse <dwmw2@infradead.org>
9 *
10 * For licensing information, see the file 'LICENCE' in this directory.
11 *
12 */
13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16#include <linux/kernel.h>
17#include <linux/mtd/mtd.h>
18#include <linux/compiler.h>
19#include <linux/sched.h> /* For cond_resched() */
20#include "nodelist.h"
21#include "debug.h"
22
23/*
24 * Check whether the user is allowed to write.
25 */
26static int jffs2_rp_can_write(struct jffs2_sb_info *c)
27{
28        uint32_t avail;
29        struct jffs2_mount_opts *opts = &c->mount_opts;
30
31        avail = c->dirty_size + c->free_size + c->unchecked_size +
32                c->erasing_size - c->resv_blocks_write * c->sector_size
33                - c->nospc_dirty_size;
34
35        if (avail < 2 * opts->rp_size)
36                jffs2_dbg(1, "rpsize %u, dirty_size %u, free_size %u, "
37                          "erasing_size %u, unchecked_size %u, "
38                          "nr_erasing_blocks %u, avail %u, resrv %u\n",
39                          opts->rp_size, c->dirty_size, c->free_size,
40                          c->erasing_size, c->unchecked_size,
41                          c->nr_erasing_blocks, avail, c->nospc_dirty_size);
42
43        if (avail > opts->rp_size)
44                return 1;
45
46        /* Always allow root */
47        if (capable(CAP_SYS_RESOURCE))
48                return 1;
49
50        jffs2_dbg(1, "forbid writing\n");
51        return 0;
52}
53
54/**
55 *      jffs2_reserve_space - request physical space to write nodes to flash
56 *      @c: superblock info
57 *      @minsize: Minimum acceptable size of allocation
58 *      @len: Returned value of allocation length
59 *      @prio: Allocation type - ALLOC_{NORMAL,DELETION}
60 *
61 *      Requests a block of physical space on the flash. Returns zero for success
62 *      and puts 'len' into the appropriate place, or returns -ENOSPC or other
63 *      error if appropriate. Doesn't return len since that's
64 *
65 *      If it returns zero, jffs2_reserve_space() also downs the per-filesystem
66 *      allocation semaphore, to prevent more than one allocation from being
67 *      active at any time. The semaphore is later released by jffs2_commit_allocation()
68 *
69 *      jffs2_reserve_space() may trigger garbage collection in order to make room
70 *      for the requested allocation.
71 */
72
73static int jffs2_do_reserve_space(struct jffs2_sb_info *c,  uint32_t minsize,
74                                  uint32_t *len, uint32_t sumsize);
75
76int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
77                        uint32_t *len, int prio, uint32_t sumsize)
78{
79        int ret = -EAGAIN;
80        int blocksneeded = c->resv_blocks_write;
81        /* align it */
82        minsize = PAD(minsize);
83
84        jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize);
85        mutex_lock(&c->alloc_sem);
86
87        jffs2_dbg(1, "%s(): alloc sem got\n", __func__);
88
89        spin_lock(&c->erase_completion_lock);
90
91        /*
92         * Check if the free space is greater then size of the reserved pool.
93         * If not, only allow root to proceed with writing.
94         */
95        if (prio != ALLOC_DELETION && !jffs2_rp_can_write(c)) {
96                ret = -ENOSPC;
97                goto out;
98        }
99
100        /* this needs a little more thought (true <tglx> :)) */
101        while(ret == -EAGAIN) {
102                while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) {
103                        uint32_t dirty, avail;
104
105                        /* calculate real dirty size
106                         * dirty_size contains blocks on erase_pending_list
107                         * those blocks are counted in c->nr_erasing_blocks.
108                         * If one block is actually erased, it is not longer counted as dirty_space
109                         * but it is counted in c->nr_erasing_blocks, so we add it and subtract it
110                         * with c->nr_erasing_blocks * c->sector_size again.
111                         * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks
112                         * This helps us to force gc and pick eventually a clean block to spread the load.
113                         * We add unchecked_size here, as we hopefully will find some space to use.
114                         * This will affect the sum only once, as gc first finishes checking
115                         * of nodes.
116                         */
117                        dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
118                        if (dirty < c->nospc_dirty_size) {
119                                if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
120                                        jffs2_dbg(1, "%s(): Low on dirty space to GC, but it's a deletion. Allowing...\n",
121                                                  __func__);
122                                        break;
123                                }
124                                jffs2_dbg(1, "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n",
125                                          dirty, c->unchecked_size,
126                                          c->sector_size);
127
128                                spin_unlock(&c->erase_completion_lock);
129                                mutex_unlock(&c->alloc_sem);
130                                return -ENOSPC;
131                        }
132
133                        /* Calc possibly available space. Possibly available means that we
134                         * don't know, if unchecked size contains obsoleted nodes, which could give us some
135                         * more usable space. This will affect the sum only once, as gc first finishes checking
136                         * of nodes.
137                         + Return -ENOSPC, if the maximum possibly available space is less or equal than
138                         * blocksneeded * sector_size.
139                         * This blocks endless gc looping on a filesystem, which is nearly full, even if
140                         * the check above passes.
141                         */
142                        avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
143                        if ( (avail / c->sector_size) <= blocksneeded) {
144                                if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
145                                        jffs2_dbg(1, "%s(): Low on possibly available space, but it's a deletion. Allowing...\n",
146                                                  __func__);
147                                        break;
148                                }
149
150                                jffs2_dbg(1, "max. available size 0x%08x  < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n",
151                                          avail, blocksneeded * c->sector_size);
152                                spin_unlock(&c->erase_completion_lock);
153                                mutex_unlock(&c->alloc_sem);
154                                return -ENOSPC;
155                        }
156
157                        mutex_unlock(&c->alloc_sem);
158
159                        jffs2_dbg(1, "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, wasted_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n",
160                                  c->nr_free_blocks, c->nr_erasing_blocks,
161                                  c->free_size, c->dirty_size, c->wasted_size,
162                                  c->used_size, c->erasing_size, c->bad_size,
163                                  c->free_size + c->dirty_size +
164                                  c->wasted_size + c->used_size +
165                                  c->erasing_size + c->bad_size,
166                                  c->flash_size);
167                        spin_unlock(&c->erase_completion_lock);
168
169                        ret = jffs2_garbage_collect_pass(c);
170
171                        if (ret == -EAGAIN) {
172                                spin_lock(&c->erase_completion_lock);
173                                if (c->nr_erasing_blocks &&
174                                    list_empty(&c->erase_pending_list) &&
175                                    list_empty(&c->erase_complete_list)) {
176                                        DECLARE_WAITQUEUE(wait, current);
177                                        set_current_state(TASK_UNINTERRUPTIBLE);
178                                        add_wait_queue(&c->erase_wait, &wait);
179                                        jffs2_dbg(1, "%s waiting for erase to complete\n",
180                                                  __func__);
181                                        spin_unlock(&c->erase_completion_lock);
182
183                                        schedule();
184                                } else
185                                        spin_unlock(&c->erase_completion_lock);
186                        } else if (ret)
187                                return ret;
188
189                        cond_resched();
190
191                        if (signal_pending(current))
192                                return -EINTR;
193
194                        mutex_lock(&c->alloc_sem);
195                        spin_lock(&c->erase_completion_lock);
196                }
197
198                ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
199                if (ret) {
200                        jffs2_dbg(1, "%s(): ret is %d\n", __func__, ret);
201                }
202        }
203
204out:
205        spin_unlock(&c->erase_completion_lock);
206        if (!ret)
207                ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
208        if (ret)
209                mutex_unlock(&c->alloc_sem);
210        return ret;
211}
212
213int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
214                           uint32_t *len, uint32_t sumsize)
215{
216        int ret = -EAGAIN;
217        minsize = PAD(minsize);
218
219        jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize);
220
221        spin_lock(&c->erase_completion_lock);
222        while(ret == -EAGAIN) {
223                ret = jffs2_do_reserve_space(c, minsize, len, sumsize);
224                if (ret) {
225                        jffs2_dbg(1, "%s(): looping, ret is %d\n",
226                                  __func__, ret);
227                }
228        }
229        spin_unlock(&c->erase_completion_lock);
230        if (!ret)
231                ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, 1);
232
233        return ret;
234}
235
236
237/* Classify nextblock (clean, dirty of verydirty) and force to select an other one */
238
239static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
240{
241
242        if (c->nextblock == NULL) {
243                jffs2_dbg(1, "%s(): Erase block at 0x%08x has already been placed in a list\n",
244                          __func__, jeb->offset);
245                return;
246        }
247        /* Check, if we have a dirty block now, or if it was dirty already */
248        if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
249                c->dirty_size += jeb->wasted_size;
250                c->wasted_size -= jeb->wasted_size;
251                jeb->dirty_size += jeb->wasted_size;
252                jeb->wasted_size = 0;
253                if (VERYDIRTY(c, jeb->dirty_size)) {
254                        jffs2_dbg(1, "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
255                                  jeb->offset, jeb->free_size, jeb->dirty_size,
256                                  jeb->used_size);
257                        list_add_tail(&jeb->list, &c->very_dirty_list);
258                } else {
259                        jffs2_dbg(1, "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
260                                  jeb->offset, jeb->free_size, jeb->dirty_size,
261                                  jeb->used_size);
262                        list_add_tail(&jeb->list, &c->dirty_list);
263                }
264        } else {
265                jffs2_dbg(1, "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
266                          jeb->offset, jeb->free_size, jeb->dirty_size,
267                          jeb->used_size);
268                list_add_tail(&jeb->list, &c->clean_list);
269        }
270        c->nextblock = NULL;
271
272}
273
274/* Select a new jeb for nextblock */
275
276static int jffs2_find_nextblock(struct jffs2_sb_info *c)
277{
278        struct list_head *next;
279
280        /* Take the next block off the 'free' list */
281
282        if (list_empty(&c->free_list)) {
283
284                if (!c->nr_erasing_blocks &&
285                        !list_empty(&c->erasable_list)) {
286                        struct jffs2_eraseblock *ejeb;
287
288                        ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list);
289                        list_move_tail(&ejeb->list, &c->erase_pending_list);
290                        c->nr_erasing_blocks++;
291                        jffs2_garbage_collect_trigger(c);
292                        jffs2_dbg(1, "%s(): Triggering erase of erasable block at 0x%08x\n",
293                                  __func__, ejeb->offset);
294                }
295
296                if (!c->nr_erasing_blocks &&
297                        !list_empty(&c->erasable_pending_wbuf_list)) {
298                        jffs2_dbg(1, "%s(): Flushing write buffer\n",
299                                  __func__);
300                        /* c->nextblock is NULL, no update to c->nextblock allowed */
301                        spin_unlock(&c->erase_completion_lock);
302                        jffs2_flush_wbuf_pad(c);
303                        spin_lock(&c->erase_completion_lock);
304                        /* Have another go. It'll be on the erasable_list now */
305                        return -EAGAIN;
306                }
307
308                if (!c->nr_erasing_blocks) {
309                        /* Ouch. We're in GC, or we wouldn't have got here.
310                           And there's no space left. At all. */
311                        pr_crit("Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
312                                c->nr_erasing_blocks, c->nr_free_blocks,
313                                list_empty(&c->erasable_list) ? "yes" : "no",
314                                list_empty(&c->erasing_list) ? "yes" : "no",
315                                list_empty(&c->erase_pending_list) ? "yes" : "no");
316                        return -ENOSPC;
317                }
318
319                spin_unlock(&c->erase_completion_lock);
320                /* Don't wait for it; just erase one right now */
321                jffs2_erase_pending_blocks(c, 1);
322                spin_lock(&c->erase_completion_lock);
323
324                /* An erase may have failed, decreasing the
325                   amount of free space available. So we must
326                   restart from the beginning */
327                return -EAGAIN;
328        }
329
330        next = c->free_list.next;
331        list_del(next);
332        c->nextblock = list_entry(next, struct jffs2_eraseblock, list);
333        c->nr_free_blocks--;
334
335        jffs2_sum_reset_collected(c->summary); /* reset collected summary */
336
337#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
338        /* adjust write buffer offset, else we get a non contiguous write bug */
339        if (!(c->wbuf_ofs % c->sector_size) && !c->wbuf_len)
340                c->wbuf_ofs = 0xffffffff;
341#endif
342
343        jffs2_dbg(1, "%s(): new nextblock = 0x%08x\n",
344                  __func__, c->nextblock->offset);
345
346        return 0;
347}
348
349/* Called with alloc sem _and_ erase_completion_lock */
350static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
351                                  uint32_t *len, uint32_t sumsize)
352{
353        struct jffs2_eraseblock *jeb = c->nextblock;
354        uint32_t reserved_size;                         /* for summary information at the end of the jeb */
355        int ret;
356
357 restart:
358        reserved_size = 0;
359
360        if (jffs2_sum_active() && (sumsize != JFFS2_SUMMARY_NOSUM_SIZE)) {
361                                                        /* NOSUM_SIZE means not to generate summary */
362
363                if (jeb) {
364                        reserved_size = PAD(sumsize + c->summary->sum_size + JFFS2_SUMMARY_FRAME_SIZE);
365                        dbg_summary("minsize=%d , jeb->free=%d ,"
366                                                "summary->size=%d , sumsize=%d\n",
367                                                minsize, jeb->free_size,
368                                                c->summary->sum_size, sumsize);
369                }
370
371                /* Is there enough space for writing out the current node, or we have to
372                   write out summary information now, close this jeb and select new nextblock? */
373                if (jeb && (PAD(minsize) + PAD(c->summary->sum_size + sumsize +
374                                        JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size)) {
375
376                        /* Has summary been disabled for this jeb? */
377                        if (jffs2_sum_is_disabled(c->summary)) {
378                                sumsize = JFFS2_SUMMARY_NOSUM_SIZE;
379                                goto restart;
380                        }
381
382                        /* Writing out the collected summary information */
383                        dbg_summary("generating summary for 0x%08x.\n", jeb->offset);
384                        ret = jffs2_sum_write_sumnode(c);
385
386                        if (ret)
387                                return ret;
388
389                        if (jffs2_sum_is_disabled(c->summary)) {
390                                /* jffs2_write_sumnode() couldn't write out the summary information
391                                   diabling summary for this jeb and free the collected information
392                                 */
393                                sumsize = JFFS2_SUMMARY_NOSUM_SIZE;
394                                goto restart;
395                        }
396
397                        jffs2_close_nextblock(c, jeb);
398                        jeb = NULL;
399                        /* keep always valid value in reserved_size */
400                        reserved_size = PAD(sumsize + c->summary->sum_size + JFFS2_SUMMARY_FRAME_SIZE);
401                }
402        } else {
403                if (jeb && minsize > jeb->free_size) {
404                        uint32_t waste;
405
406                        /* Skip the end of this block and file it as having some dirty space */
407                        /* If there's a pending write to it, flush now */
408
409                        if (jffs2_wbuf_dirty(c)) {
410                                spin_unlock(&c->erase_completion_lock);
411                                jffs2_dbg(1, "%s(): Flushing write buffer\n",
412                                          __func__);
413                                jffs2_flush_wbuf_pad(c);
414                                spin_lock(&c->erase_completion_lock);
415                                jeb = c->nextblock;
416                                goto restart;
417                        }
418
419                        spin_unlock(&c->erase_completion_lock);
420
421                        ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
422
423                        /* Just lock it again and continue. Nothing much can change because
424                           we hold c->alloc_sem anyway. In fact, it's not entirely clear why
425                           we hold c->erase_completion_lock in the majority of this function...
426                           but that's a question for another (more caffeine-rich) day. */
427                        spin_lock(&c->erase_completion_lock);
428
429                        if (ret)
430                                return ret;
431
432                        waste = jeb->free_size;
433                        jffs2_link_node_ref(c, jeb,
434                                            (jeb->offset + c->sector_size - waste) | REF_OBSOLETE,
435                                            waste, NULL);
436                        /* FIXME: that made it count as dirty. Convert to wasted */
437                        jeb->dirty_size -= waste;
438                        c->dirty_size -= waste;
439                        jeb->wasted_size += waste;
440                        c->wasted_size += waste;
441
442                        jffs2_close_nextblock(c, jeb);
443                        jeb = NULL;
444                }
445        }
446
447        if (!jeb) {
448
449                ret = jffs2_find_nextblock(c);
450                if (ret)
451                        return ret;
452
453                jeb = c->nextblock;
454
455                if (jeb->free_size != c->sector_size - c->cleanmarker_size) {
456                        pr_warn("Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n",
457                                jeb->offset, jeb->free_size);
458                        goto restart;
459                }
460        }
461        /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has
462           enough space */
463        *len = jeb->free_size - reserved_size;
464
465        if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
466            !jeb->first_node->next_in_ino) {
467                /* Only node in it beforehand was a CLEANMARKER node (we think).
468                   So mark it obsolete now that there's going to be another node
469                   in the block. This will reduce used_size to zero but We've
470                   already set c->nextblock so that jffs2_mark_node_obsolete()
471                   won't try to refile it to the dirty_list.
472                */
473                spin_unlock(&c->erase_completion_lock);
474                jffs2_mark_node_obsolete(c, jeb->first_node);
475                spin_lock(&c->erase_completion_lock);
476        }
477
478        jffs2_dbg(1, "%s(): Giving 0x%x bytes at 0x%x\n",
479                  __func__,
480                  *len, jeb->offset + (c->sector_size - jeb->free_size));
481        return 0;
482}
483
484/**
485 *      jffs2_add_physical_node_ref - add a physical node reference to the list
486 *      @c: superblock info
487 *      @new: new node reference to add
488 *      @len: length of this physical node
489 *
490 *      Should only be used to report nodes for which space has been allocated
491 *      by jffs2_reserve_space.
492 *
493 *      Must be called with the alloc_sem held.
494 */
495
496struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
497                                                       uint32_t ofs, uint32_t len,
498                                                       struct jffs2_inode_cache *ic)
499{
500        struct jffs2_eraseblock *jeb;
501        struct jffs2_raw_node_ref *new;
502
503        jeb = &c->blocks[ofs / c->sector_size];
504
505        jffs2_dbg(1, "%s(): Node at 0x%x(%d), size 0x%x\n",
506                  __func__, ofs & ~3, ofs & 3, len);
507#if 1
508        /* Allow non-obsolete nodes only to be added at the end of c->nextblock,
509           if c->nextblock is set. Note that wbuf.c will file obsolete nodes
510           even after refiling c->nextblock */
511        if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE))
512            && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) {
513                pr_warn("argh. node added in wrong place at 0x%08x(%d)\n",
514                        ofs & ~3, ofs & 3);
515                if (c->nextblock)
516                        pr_warn("nextblock 0x%08x", c->nextblock->offset);
517                else
518                        pr_warn("No nextblock");
519                pr_cont(", expected at %08x\n",
520                        jeb->offset + (c->sector_size - jeb->free_size));
521                return ERR_PTR(-EINVAL);
522        }
523#endif
524        spin_lock(&c->erase_completion_lock);
525
526        new = jffs2_link_node_ref(c, jeb, ofs, len, ic);
527
528        if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) {
529                /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
530                jffs2_dbg(1, "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
531                          jeb->offset, jeb->free_size, jeb->dirty_size,
532                          jeb->used_size);
533                if (jffs2_wbuf_dirty(c)) {
534                        /* Flush the last write in the block if it's outstanding */
535                        spin_unlock(&c->erase_completion_lock);
536                        jffs2_flush_wbuf_pad(c);
537                        spin_lock(&c->erase_completion_lock);
538                }
539
540                list_add_tail(&jeb->list, &c->clean_list);
541                c->nextblock = NULL;
542        }
543        jffs2_dbg_acct_sanity_check_nolock(c,jeb);
544        jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
545
546        spin_unlock(&c->erase_completion_lock);
547
548        return new;
549}
550
551
552void jffs2_complete_reservation(struct jffs2_sb_info *c)
553{
554        jffs2_dbg(1, "jffs2_complete_reservation()\n");
555        spin_lock(&c->erase_completion_lock);
556        jffs2_garbage_collect_trigger(c);
557        spin_unlock(&c->erase_completion_lock);
558        mutex_unlock(&c->alloc_sem);
559}
560
561static inline int on_list(struct list_head *obj, struct list_head *head)
562{
563        struct list_head *this;
564
565        list_for_each(this, head) {
566                if (this == obj) {
567                        jffs2_dbg(1, "%p is on list at %p\n", obj, head);
568                        return 1;
569
570                }
571        }
572        return 0;
573}
574
575void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref)
576{
577        struct jffs2_eraseblock *jeb;
578        int blocknr;
579        struct jffs2_unknown_node n;
580        int ret, addedsize;
581        size_t retlen;
582        uint32_t freed_len;
583
584        if(unlikely(!ref)) {
585                pr_notice("EEEEEK. jffs2_mark_node_obsolete called with NULL node\n");
586                return;
587        }
588        if (ref_obsolete(ref)) {
589                jffs2_dbg(1, "%s(): called with already obsolete node at 0x%08x\n",
590                          __func__, ref_offset(ref));
591                return;
592        }
593        blocknr = ref->flash_offset / c->sector_size;
594        if (blocknr >= c->nr_blocks) {
595                pr_notice("raw node at 0x%08x is off the end of device!\n",
596                          ref->flash_offset);
597                BUG();
598        }
599        jeb = &c->blocks[blocknr];
600
601        if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
602            !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
603                /* Hm. This may confuse static lock analysis. If any of the above
604                   three conditions is false, we're going to return from this
605                   function without actually obliterating any nodes or freeing
606                   any jffs2_raw_node_refs. So we don't need to stop erases from
607                   happening, or protect against people holding an obsolete
608                   jffs2_raw_node_ref without the erase_completion_lock. */
609                mutex_lock(&c->erase_free_sem);
610        }
611
612        spin_lock(&c->erase_completion_lock);
613
614        freed_len = ref_totlen(c, jeb, ref);
615
616        if (ref_flags(ref) == REF_UNCHECKED) {
617                D1(if (unlikely(jeb->unchecked_size < freed_len)) {
618                                pr_notice("raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n",
619                                          freed_len, blocknr,
620                                          ref->flash_offset, jeb->used_size);
621                        BUG();
622                })
623                        jffs2_dbg(1, "Obsoleting previously unchecked node at 0x%08x of len %x\n",
624                                  ref_offset(ref), freed_len);
625                jeb->unchecked_size -= freed_len;
626                c->unchecked_size -= freed_len;
627        } else {
628                D1(if (unlikely(jeb->used_size < freed_len)) {
629                                pr_notice("raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n",
630                                          freed_len, blocknr,
631                                          ref->flash_offset, jeb->used_size);
632                        BUG();
633                })
634                        jffs2_dbg(1, "Obsoleting node at 0x%08x of len %#x: ",
635                                  ref_offset(ref), freed_len);
636                jeb->used_size -= freed_len;
637                c->used_size -= freed_len;
638        }
639
640        // Take care, that wasted size is taken into concern
641        if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + freed_len)) && jeb != c->nextblock) {
642                jffs2_dbg(1, "Dirtying\n");
643                addedsize = freed_len;
644                jeb->dirty_size += freed_len;
645                c->dirty_size += freed_len;
646
647                /* Convert wasted space to dirty, if not a bad block */
648                if (jeb->wasted_size) {
649                        if (on_list(&jeb->list, &c->bad_used_list)) {
650                                jffs2_dbg(1, "Leaving block at %08x on the bad_used_list\n",
651                                          jeb->offset);
652                                addedsize = 0; /* To fool the refiling code later */
653                        } else {
654                                jffs2_dbg(1, "Converting %d bytes of wasted space to dirty in block at %08x\n",
655                                          jeb->wasted_size, jeb->offset);
656                                addedsize += jeb->wasted_size;
657                                jeb->dirty_size += jeb->wasted_size;
658                                c->dirty_size += jeb->wasted_size;
659                                c->wasted_size -= jeb->wasted_size;
660                                jeb->wasted_size = 0;
661                        }
662                }
663        } else {
664                jffs2_dbg(1, "Wasting\n");
665                addedsize = 0;
666                jeb->wasted_size += freed_len;
667                c->wasted_size += freed_len;
668        }
669        ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
670
671        jffs2_dbg_acct_sanity_check_nolock(c, jeb);
672        jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
673
674        if (c->flags & JFFS2_SB_FLAG_SCANNING) {
675                /* Flash scanning is in progress. Don't muck about with the block
676                   lists because they're not ready yet, and don't actually
677                   obliterate nodes that look obsolete. If they weren't
678                   marked obsolete on the flash at the time they _became_
679                   obsolete, there was probably a reason for that. */
680                spin_unlock(&c->erase_completion_lock);
681                /* We didn't lock the erase_free_sem */
682                return;
683        }
684
685        if (jeb == c->nextblock) {
686                jffs2_dbg(2, "Not moving nextblock 0x%08x to dirty/erase_pending list\n",
687                          jeb->offset);
688        } else if (!jeb->used_size && !jeb->unchecked_size) {
689                if (jeb == c->gcblock) {
690                        jffs2_dbg(1, "gcblock at 0x%08x completely dirtied. Clearing gcblock...\n",
691                                  jeb->offset);
692                        c->gcblock = NULL;
693                } else {
694                        jffs2_dbg(1, "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n",
695                                  jeb->offset);
696                        list_del(&jeb->list);
697                }
698                if (jffs2_wbuf_dirty(c)) {
699                        jffs2_dbg(1, "...and adding to erasable_pending_wbuf_list\n");
700                        list_add_tail(&jeb->list, &c->erasable_pending_wbuf_list);
701                } else {
702                        if (jiffies & 127) {
703                                /* Most of the time, we just erase it immediately. Otherwise we
704                                   spend ages scanning it on mount, etc. */
705                                jffs2_dbg(1, "...and adding to erase_pending_list\n");
706                                list_add_tail(&jeb->list, &c->erase_pending_list);
707                                c->nr_erasing_blocks++;
708                                jffs2_garbage_collect_trigger(c);
709                        } else {
710                                /* Sometimes, however, we leave it elsewhere so it doesn't get
711                                   immediately reused, and we spread the load a bit. */
712                                jffs2_dbg(1, "...and adding to erasable_list\n");
713                                list_add_tail(&jeb->list, &c->erasable_list);
714                        }
715                }
716                jffs2_dbg(1, "Done OK\n");
717        } else if (jeb == c->gcblock) {
718                jffs2_dbg(2, "Not moving gcblock 0x%08x to dirty_list\n",
719                          jeb->offset);
720        } else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - addedsize)) {
721                jffs2_dbg(1, "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n",
722                          jeb->offset);
723                list_del(&jeb->list);
724                jffs2_dbg(1, "...and adding to dirty_list\n");
725                list_add_tail(&jeb->list, &c->dirty_list);
726        } else if (VERYDIRTY(c, jeb->dirty_size) &&
727                   !VERYDIRTY(c, jeb->dirty_size - addedsize)) {
728                jffs2_dbg(1, "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n",
729                          jeb->offset);
730                list_del(&jeb->list);
731                jffs2_dbg(1, "...and adding to very_dirty_list\n");
732                list_add_tail(&jeb->list, &c->very_dirty_list);
733        } else {
734                jffs2_dbg(1, "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
735                          jeb->offset, jeb->free_size, jeb->dirty_size,
736                          jeb->used_size);
737        }
738
739        spin_unlock(&c->erase_completion_lock);
740
741        if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c) ||
742                (c->flags & JFFS2_SB_FLAG_BUILDING)) {
743                /* We didn't lock the erase_free_sem */
744                return;
745        }
746
747        /* The erase_free_sem is locked, and has been since before we marked the node obsolete
748           and potentially put its eraseblock onto the erase_pending_list. Thus, we know that
749           the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet
750           by jffs2_free_jeb_node_refs() in erase.c. Which is nice. */
751
752        jffs2_dbg(1, "obliterating obsoleted node at 0x%08x\n",
753                  ref_offset(ref));
754        ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
755        if (ret) {
756                pr_warn("Read error reading from obsoleted node at 0x%08x: %d\n",
757                        ref_offset(ref), ret);
758                goto out_erase_sem;
759        }
760        if (retlen != sizeof(n)) {
761                pr_warn("Short read from obsoleted node at 0x%08x: %zd\n",
762                        ref_offset(ref), retlen);
763                goto out_erase_sem;
764        }
765        if (PAD(je32_to_cpu(n.totlen)) != PAD(freed_len)) {
766                pr_warn("Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n",
767                        je32_to_cpu(n.totlen), freed_len);
768                goto out_erase_sem;
769        }
770        if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) {
771                jffs2_dbg(1, "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n",
772                          ref_offset(ref), je16_to_cpu(n.nodetype));
773                goto out_erase_sem;
774        }
775        /* XXX FIXME: This is ugly now */
776        n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE);
777        ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
778        if (ret) {
779                pr_warn("Write error in obliterating obsoleted node at 0x%08x: %d\n",
780                        ref_offset(ref), ret);
781                goto out_erase_sem;
782        }
783        if (retlen != sizeof(n)) {
784                pr_warn("Short write in obliterating obsoleted node at 0x%08x: %zd\n",
785                        ref_offset(ref), retlen);
786                goto out_erase_sem;
787        }
788
789        /* Nodes which have been marked obsolete no longer need to be
790           associated with any inode. Remove them from the per-inode list.
791
792           Note we can't do this for NAND at the moment because we need
793           obsolete dirent nodes to stay on the lists, because of the
794           horridness in jffs2_garbage_collect_deletion_dirent(). Also
795           because we delete the inocache, and on NAND we need that to
796           stay around until all the nodes are actually erased, in order
797           to stop us from giving the same inode number to another newly
798           created inode. */
799        if (ref->next_in_ino) {
800                struct jffs2_inode_cache *ic;
801                struct jffs2_raw_node_ref **p;
802
803                spin_lock(&c->erase_completion_lock);
804
805                ic = jffs2_raw_ref_to_ic(ref);
806                for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino))
807                        ;
808
809                *p = ref->next_in_ino;
810                ref->next_in_ino = NULL;
811
812                switch (ic->class) {
813#ifdef CONFIG_JFFS2_FS_XATTR
814                        case RAWNODE_CLASS_XATTR_DATUM:
815                                jffs2_release_xattr_datum(c, (struct jffs2_xattr_datum *)ic);
816                                break;
817                        case RAWNODE_CLASS_XATTR_REF:
818                                jffs2_release_xattr_ref(c, (struct jffs2_xattr_ref *)ic);
819                                break;
820#endif
821                        default:
822                                if (ic->nodes == (void *)ic && ic->pino_nlink == 0)
823                                        jffs2_del_ino_cache(c, ic);
824                                break;
825                }
826                spin_unlock(&c->erase_completion_lock);
827        }
828
829 out_erase_sem:
830        mutex_unlock(&c->erase_free_sem);
831}
832
833int jffs2_thread_should_wake(struct jffs2_sb_info *c)
834{
835        int ret = 0;
836        uint32_t dirty;
837        int nr_very_dirty = 0;
838        struct jffs2_eraseblock *jeb;
839
840        if (!list_empty(&c->erase_complete_list) ||
841            !list_empty(&c->erase_pending_list))
842                return 1;
843
844        if (c->unchecked_size) {
845                jffs2_dbg(1, "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n",
846                          c->unchecked_size, c->checked_ino);
847                return 1;
848        }
849
850        /* dirty_size contains blocks on erase_pending_list
851         * those blocks are counted in c->nr_erasing_blocks.
852         * If one block is actually erased, it is not longer counted as dirty_space
853         * but it is counted in c->nr_erasing_blocks, so we add it and subtract it
854         * with c->nr_erasing_blocks * c->sector_size again.
855         * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks
856         * This helps us to force gc and pick eventually a clean block to spread the load.
857         */
858        dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size;
859
860        if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
861                        (dirty > c->nospc_dirty_size))
862                ret = 1;
863
864        list_for_each_entry(jeb, &c->very_dirty_list, list) {
865                nr_very_dirty++;
866                if (nr_very_dirty == c->vdirty_blocks_gctrigger) {
867                        ret = 1;
868                        /* In debug mode, actually go through and count them all */
869                        D1(continue);
870                        break;
871                }
872        }
873
874        jffs2_dbg(1, "%s(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x, vdirty_blocks %d: %s\n",
875                  __func__, c->nr_free_blocks, c->nr_erasing_blocks,
876                  c->dirty_size, nr_very_dirty, ret ? "yes" : "no");
877
878        return ret;
879}
Note: See TracBrowser for help on using the repository browser.