2 * JFFS2 -- Journalling Flash File System, Version 2.
4 * Copyright (C) 2001-2003 Red Hat, Inc.
6 * Created by David Woodhouse <dwmw2@redhat.com>
8 * For licensing information, see the file 'LICENCE' in this directory.
10 * $Id: erase.c,v 1.53 2003/10/08 17:22:54 dwmw2 Exp $
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/mtd/mtd.h>
17 #include <linux/compiler.h>
18 #include <linux/crc32.h>
19 #include <linux/sched.h>
20 #include <linux/pagemap.h>
23 struct erase_priv_struct
{
24 struct jffs2_eraseblock
*jeb
;
25 struct jffs2_sb_info
*c
;
29 static void jffs2_erase_callback(struct erase_info
*);
31 static void jffs2_erase_failed(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
);
32 static void jffs2_erase_succeeded(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
);
33 static void jffs2_free_all_node_refs(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
);
34 static void jffs2_mark_erased_block(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
);
36 void jffs2_erase_block(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
)
40 ret
= jffs2_flash_erase(c
, jeb
);
42 jffs2_erase_succeeded(c
, jeb
);
46 struct erase_info
*instr
;
48 instr
= kmalloc(sizeof(struct erase_info
) + sizeof(struct erase_priv_struct
), GFP_KERNEL
);
50 printk(KERN_WARNING
"kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
51 spin_lock(&c
->erase_completion_lock
);
53 list_add(&jeb
->list
, &c
->erase_pending_list
);
54 c
->erasing_size
-= c
->sector_size
;
55 c
->dirty_size
+= c
->sector_size
;
56 jeb
->dirty_size
= c
->sector_size
;
57 spin_unlock(&c
->erase_completion_lock
);
61 memset(instr
, 0, sizeof(*instr
));
64 instr
->addr
= jeb
->offset
;
65 instr
->len
= c
->sector_size
;
66 instr
->callback
= jffs2_erase_callback
;
67 instr
->priv
= (unsigned long)(&instr
[1]);
69 ((struct erase_priv_struct
*)instr
->priv
)->jeb
= jeb
;
70 ((struct erase_priv_struct
*)instr
->priv
)->c
= c
;
72 /* NAND , read out the fail counter, if possible */
73 if (!jffs2_can_mark_obsolete(c
))
74 jffs2_nand_read_failcnt(c
,jeb
);
76 ret
= c
->mtd
->erase(c
->mtd
, instr
);
83 if (ret
== -ENOMEM
|| ret
== -EAGAIN
) {
84 /* Erase failed immediately. Refile it on the list */
85 D1(printk(KERN_DEBUG
"Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb
->offset
, ret
));
86 spin_lock(&c
->erase_completion_lock
);
88 list_add(&jeb
->list
, &c
->erase_pending_list
);
89 c
->erasing_size
-= c
->sector_size
;
90 c
->dirty_size
+= c
->sector_size
;
91 jeb
->dirty_size
= c
->sector_size
;
92 spin_unlock(&c
->erase_completion_lock
);
97 printk(KERN_WARNING
"Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb
->offset
);
99 printk(KERN_WARNING
"Erase at 0x%08x failed immediately: errno %d\n", jeb
->offset
, ret
);
101 jffs2_erase_failed(c
, jeb
);
104 void jffs2_erase_pending_blocks(struct jffs2_sb_info
*c
)
106 struct jffs2_eraseblock
*jeb
;
108 down(&c
->erase_free_sem
);
110 spin_lock(&c
->erase_completion_lock
);
112 while (!list_empty(&c
->erase_complete_list
) ||
113 !list_empty(&c
->erase_pending_list
)) {
115 if (!list_empty(&c
->erase_complete_list
)) {
116 jeb
= list_entry(c
->erase_complete_list
.next
, struct jffs2_eraseblock
, list
);
117 list_del(&jeb
->list
);
118 spin_unlock(&c
->erase_completion_lock
);
119 jffs2_mark_erased_block(c
, jeb
);
121 } else if (!list_empty(&c
->erase_pending_list
)) {
122 jeb
= list_entry(c
->erase_pending_list
.next
, struct jffs2_eraseblock
, list
);
123 D1(printk(KERN_DEBUG
"Starting erase of pending block 0x%08x\n", jeb
->offset
));
124 list_del(&jeb
->list
);
125 c
->erasing_size
+= c
->sector_size
;
126 c
->wasted_size
-= jeb
->wasted_size
;
127 c
->free_size
-= jeb
->free_size
;
128 c
->used_size
-= jeb
->used_size
;
129 c
->dirty_size
-= jeb
->dirty_size
;
130 jeb
->wasted_size
= jeb
->used_size
= jeb
->dirty_size
= jeb
->free_size
= 0;
131 jffs2_free_all_node_refs(c
, jeb
);
132 list_add(&jeb
->list
, &c
->erasing_list
);
133 spin_unlock(&c
->erase_completion_lock
);
135 jffs2_erase_block(c
, jeb
);
143 spin_lock(&c
->erase_completion_lock
);
146 spin_unlock(&c
->erase_completion_lock
);
147 D1(printk(KERN_DEBUG
"jffs2_erase_pending_blocks completed\n"));
149 up(&c
->erase_free_sem
);
152 static void jffs2_erase_succeeded(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
)
154 D1(printk(KERN_DEBUG
"Erase completed successfully at 0x%08x\n", jeb
->offset
));
155 spin_lock(&c
->erase_completion_lock
);
156 list_del(&jeb
->list
);
157 list_add_tail(&jeb
->list
, &c
->erase_complete_list
);
158 spin_unlock(&c
->erase_completion_lock
);
159 /* Ensure that kupdated calls us again to mark them clean */
160 jffs2_erase_pending_trigger(c
);
163 static void jffs2_erase_failed(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
)
165 spin_lock(&c
->erase_completion_lock
);
166 c
->erasing_size
-= c
->sector_size
;
167 c
->bad_size
+= c
->sector_size
;
168 list_del(&jeb
->list
);
169 list_add(&jeb
->list
, &c
->bad_list
);
170 c
->nr_erasing_blocks
--;
171 spin_unlock(&c
->erase_completion_lock
);
172 wake_up(&c
->erase_wait
);
176 static void jffs2_erase_callback(struct erase_info
*instr
)
178 struct erase_priv_struct
*priv
= (void *)instr
->priv
;
180 if(instr
->state
!= MTD_ERASE_DONE
) {
181 printk(KERN_WARNING
"Erase at 0x%08x finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", instr
->addr
, instr
->state
);
182 jffs2_erase_failed(priv
->c
, priv
->jeb
);
184 jffs2_erase_succeeded(priv
->c
, priv
->jeb
);
190 /* Hmmm. Maybe we should accept the extra space it takes and make
191 this a standard doubly-linked list? */
192 static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info
*c
,
193 struct jffs2_raw_node_ref
*ref
, struct jffs2_eraseblock
*jeb
)
195 struct jffs2_inode_cache
*ic
= NULL
;
196 struct jffs2_raw_node_ref
**prev
;
198 prev
= &ref
->next_in_ino
;
200 /* Walk the inode's list once, removing any nodes from this eraseblock */
202 if (!(*prev
)->next_in_ino
) {
203 /* We're looking at the jffs2_inode_cache, which is
204 at the end of the linked list. Stash it and continue
205 from the beginning of the list */
206 ic
= (struct jffs2_inode_cache
*)(*prev
);
211 if (((*prev
)->flash_offset
& ~(c
->sector_size
-1)) == jeb
->offset
) {
212 /* It's in the block we're erasing */
213 struct jffs2_raw_node_ref
*this;
216 *prev
= this->next_in_ino
;
217 this->next_in_ino
= NULL
;
224 /* Not to be deleted. Skip */
225 prev
= &((*prev
)->next_in_ino
);
230 printk(KERN_WARNING
"inode_cache not found in remove_node_refs()!!\n");
234 D1(printk(KERN_DEBUG
"Removed nodes in range 0x%08x-0x%08x from ino #%u\n",
235 jeb
->offset
, jeb
->offset
+ c
->sector_size
, ic
->ino
));
239 struct jffs2_raw_node_ref
*this;
240 printk(KERN_DEBUG
"After remove_node_refs_from_ino_list: \n" KERN_DEBUG
);
245 printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this));
247 printk("\n" KERN_DEBUG
);
250 this = this->next_in_ino
;
255 if (ic
->nodes
== (void *)ic
) {
256 D1(printk(KERN_DEBUG
"inocache for ino #%u is all gone now. Freeing\n", ic
->ino
));
257 jffs2_del_ino_cache(c
, ic
);
258 jffs2_free_inode_cache(ic
);
262 static void jffs2_free_all_node_refs(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
)
264 struct jffs2_raw_node_ref
*ref
;
265 D1(printk(KERN_DEBUG
"Freeing all node refs for eraseblock offset 0x%08x\n", jeb
->offset
));
266 while(jeb
->first_node
) {
267 ref
= jeb
->first_node
;
268 jeb
->first_node
= ref
->next_phys
;
270 /* Remove from the inode-list */
271 if (ref
->next_in_ino
)
272 jffs2_remove_node_refs_from_ino_list(c
, ref
, jeb
);
273 /* else it was a non-inode node or already removed, so don't bother */
275 jffs2_free_raw_node_ref(ref
);
277 jeb
->last_node
= NULL
;
280 void jffs2_erase_pending_trigger(struct jffs2_sb_info
*c
)
282 OFNI_BS_2SFFJ(c
)->s_dirt
= 1;
285 static void jffs2_mark_erased_block(struct jffs2_sb_info
*c
, struct jffs2_eraseblock
*jeb
)
287 struct jffs2_raw_node_ref
*marker_ref
= NULL
;
292 if (!jffs2_cleanmarker_oob(c
)) {
293 marker_ref
= jffs2_alloc_raw_node_ref();
295 printk(KERN_WARNING
"Failed to allocate raw node ref for clean marker\n");
296 /* Stick it back on the list from whence it came and come back later */
297 jffs2_erase_pending_trigger(c
);
298 spin_lock(&c
->erase_completion_lock
);
299 list_add(&jeb
->list
, &c
->erase_complete_list
);
300 spin_unlock(&c
->erase_completion_lock
);
304 ebuf
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
306 printk(KERN_WARNING
"Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb
->offset
);
308 uint32_t ofs
= jeb
->offset
;
310 D1(printk(KERN_DEBUG
"Verifying erase at 0x%08x\n", jeb
->offset
));
311 while(ofs
< jeb
->offset
+ c
->sector_size
) {
312 uint32_t readlen
= min((uint32_t)PAGE_SIZE
, jeb
->offset
+ c
->sector_size
- ofs
);
315 ret
= jffs2_flash_read(c
, ofs
, readlen
, &retlen
, ebuf
);
317 printk(KERN_WARNING
"Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs
, ret
);
320 if (retlen
!= readlen
) {
321 printk(KERN_WARNING
"Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs
, readlen
, retlen
);
324 for (i
=0; i
<readlen
; i
+= sizeof(unsigned long)) {
325 /* It's OK. We know it's properly aligned */
326 unsigned long datum
= *(unsigned long *)(&ebuf
[i
]);
328 printk(KERN_WARNING
"Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum
, ofs
+ i
);
330 if (!jffs2_cleanmarker_oob(c
))
331 jffs2_free_raw_node_ref(marker_ref
);
333 jffs2_write_nand_badblock( c
,jeb
);
336 spin_lock(&c
->erase_completion_lock
);
337 c
->erasing_size
-= c
->sector_size
;
338 c
->bad_size
+= c
->sector_size
;
340 list_add_tail(&jeb
->list
, &c
->bad_list
);
341 c
->nr_erasing_blocks
--;
342 spin_unlock(&c
->erase_completion_lock
);
343 wake_up(&c
->erase_wait
);
353 /* Write the erase complete marker */
354 D1(printk(KERN_DEBUG
"Writing erased marker to block at 0x%08x\n", jeb
->offset
));
355 if (jffs2_cleanmarker_oob(c
)) {
357 if (jffs2_write_nand_cleanmarker(c
, jeb
))
360 jeb
->first_node
= jeb
->last_node
= NULL
;
362 jeb
->free_size
= c
->sector_size
;
365 jeb
->wasted_size
= 0;
367 struct jffs2_unknown_node marker
= {
368 .magic
= cpu_to_je16(JFFS2_MAGIC_BITMASK
),
369 .nodetype
= cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER
),
370 .totlen
= cpu_to_je32(c
->cleanmarker_size
)
373 marker
.hdr_crc
= cpu_to_je32(crc32(0, &marker
, je32_to_cpu(marker
.totlen
) - 4));
375 ret
= jffs2_flash_write(c
, jeb
->offset
, je32_to_cpu(marker
.totlen
), &retlen
, (char *)&marker
);
377 printk(KERN_WARNING
"Write clean marker to block at 0x%08x failed: %d\n",
381 if (retlen
!= je32_to_cpu(marker
.totlen
)) {
382 printk(KERN_WARNING
"Short write to newly-erased block at 0x%08x: Wanted %d, got %zd\n",
383 jeb
->offset
, je32_to_cpu(marker
.totlen
), retlen
);
387 marker_ref
->next_in_ino
= NULL
;
388 marker_ref
->next_phys
= NULL
;
389 marker_ref
->flash_offset
= jeb
->offset
| REF_NORMAL
;
390 marker_ref
->totlen
= PAD(je32_to_cpu(marker
.totlen
));
392 jeb
->first_node
= jeb
->last_node
= marker_ref
;
394 jeb
->free_size
= c
->sector_size
- marker_ref
->totlen
;
395 jeb
->used_size
= marker_ref
->totlen
;
397 jeb
->wasted_size
= 0;
400 spin_lock(&c
->erase_completion_lock
);
401 c
->erasing_size
-= c
->sector_size
;
402 c
->free_size
+= jeb
->free_size
;
403 c
->used_size
+= jeb
->used_size
;
405 ACCT_SANITY_CHECK(c
,jeb
);
406 D1(ACCT_PARANOIA_CHECK(jeb
));
408 list_add_tail(&jeb
->list
, &c
->free_list
);
409 c
->nr_erasing_blocks
--;
411 spin_unlock(&c
->erase_completion_lock
);
412 wake_up(&c
->erase_wait
);