--- zzzz-none-000/linux-2.4.17/fs/jffs2/erase.c 2001-10-04 22:13:18.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/fs/jffs2/erase.c 2004-11-24 13:22:18.000000000 +0000 @@ -1,7 +1,7 @@ /* * JFFS2 -- Journalling Flash File System, Version 2. * - * Copyright (C) 2001 Red Hat, Inc. + * Copyright (C) 2001, 2002 Red Hat, Inc. * * Created by David Woodhouse * @@ -31,13 +31,13 @@ * provisions above, a recipient may use your version of this file * under either the RHEPL or the GPL. * - * $Id: erase.c,v 1.23 2001/09/19 21:51:11 dwmw2 Exp $ + * $Id: erase.c,v 1.1.1.1 2003/06/23 22:18:37 jharrell Exp $ * */ + #include #include #include -#include #include #include "nodelist.h" #include "crc32.h" @@ -48,12 +48,13 @@ }; static void jffs2_erase_callback(struct erase_info *); +static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) { - struct erase_info *instr; int ret; + struct erase_info *instr; instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); if (!instr) { @@ -78,9 +79,11 @@ ((struct erase_priv_struct *)instr->priv)->c = c; ret = c->mtd->erase(c->mtd, instr); - if (!ret) { + if (!ret) return; - } + + kfree(instr); + if (ret == -ENOMEM || ret == -EAGAIN) { /* Erase failed immediately. Refile it on the list */ D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret)); @@ -89,7 +92,6 @@ list_add(&jeb->list, &c->erase_pending_list); c->erasing_size -= c->sector_size; spin_unlock_bh(&c->erase_completion_lock); - kfree(instr); return; } @@ -97,6 +99,7 @@ printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset); else printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret); + spin_lock_bh(&c->erase_completion_lock); list_del(&jeb->list); list_add(&jeb->list, &c->bad_list); @@ -105,7 +108,6 @@ c->erasing_size -= c->sector_size; spin_unlock_bh(&c->erase_completion_lock); wake_up(&c->erase_wait); - kfree(instr); } void jffs2_erase_pending_blocks(struct jffs2_sb_info *c) @@ -130,9 +132,11 @@ spin_unlock_bh(&c->erase_completion_lock); jffs2_erase_block(c, jeb); + /* Be nice */ if (current->need_resched) schedule(); + spin_lock_bh(&c->erase_completion_lock); } spin_unlock_bh(&c->erase_completion_lock); @@ -140,26 +144,37 @@ } +static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) +{ + D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset)); + spin_lock(&c->erase_completion_lock); + list_del(&jeb->list); + list_add_tail(&jeb->list, &c->erase_complete_list); + spin_unlock(&c->erase_completion_lock); +} + + +static inline void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) +{ + spin_lock(&c->erase_completion_lock); + c->erasing_size -= c->sector_size; + c->bad_size += c->sector_size; + list_del(&jeb->list); + list_add(&jeb->list, &c->bad_list); + c->nr_erasing_blocks--; + spin_unlock(&c->erase_completion_lock); + wake_up(&c->erase_wait); +} + static void jffs2_erase_callback(struct erase_info *instr) { struct erase_priv_struct *priv = (void *)instr->priv; if(instr->state != MTD_ERASE_DONE) { printk(KERN_WARNING "Erase at 0x%08x finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", instr->addr, instr->state); - spin_lock(&priv->c->erase_completion_lock); - priv->c->erasing_size -= priv->c->sector_size; - priv->c->bad_size += priv->c->sector_size; - list_del(&priv->jeb->list); - list_add(&priv->jeb->list, &priv->c->bad_list); - priv->c->nr_erasing_blocks--; - spin_unlock(&priv->c->erase_completion_lock); - wake_up(&priv->c->erase_wait); + jffs2_erase_failed(priv->c, priv->jeb); } else { - D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", instr->addr)); - spin_lock(&priv->c->erase_completion_lock); - list_del(&priv->jeb->list); - list_add_tail(&priv->jeb->list, &priv->c->erase_complete_list); - spin_unlock(&priv->c->erase_completion_lock); + jffs2_erase_succeeded(priv->c, priv->jeb); } /* Make sure someone picks up the block off the erase_complete list */ OFNI_BS_2SFFJ(priv->c)->s_dirt = 1; @@ -215,8 +230,8 @@ D2({ int i=0; - struct jffs2_raw_node_ref *this; - printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG); + struct jffs2_raw_node_ref *this; + printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG); this = ic->nodes; @@ -267,7 +282,7 @@ struct jffs2_eraseblock *jeb; struct jffs2_raw_node_ref *marker_ref; unsigned char *ebuf; - ssize_t retlen; + size_t retlen; int ret; marker.hdr_crc = crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4); @@ -290,14 +305,14 @@ if (!ebuf) { printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb->offset); } else { - __u32 ofs = jeb->offset; + uint32_t ofs = jeb->offset; D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset)); while(ofs < jeb->offset + c->sector_size) { - __u32 readlen = min((__u32)PAGE_SIZE, jeb->offset + c->sector_size - ofs); + uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs); int i; - ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf); + ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); if (ret < 0) { printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); goto bad; @@ -333,7 +348,7 @@ /* Write the erase complete marker */ D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset)); - ret = c->mtd->write(c->mtd, jeb->offset, sizeof(marker), &retlen, (char *)&marker); + ret = jffs2_flash_write(c, jeb->offset, sizeof(marker), &retlen, (char *)&marker); if (ret) { printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n", jeb->offset, ret);