Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * JFFS2 -- Journalling Flash File System, Version 2.
0003  *
0004  * Copyright © 2001-2007 Red Hat, Inc.
0005  * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
0006  *
0007  * Created by David Woodhouse <dwmw2@infradead.org>
0008  *
0009  * For licensing information, see the file 'LICENCE' in this directory.
0010  *
0011  */
0012 
0013 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0014 
0015 #include <linux/kernel.h>
0016 #include <linux/slab.h>
0017 #include <linux/mtd/mtd.h>
0018 #include <linux/compiler.h>
0019 #include <linux/crc32.h>
0020 #include <linux/sched.h>
0021 #include <linux/pagemap.h>
0022 #include "nodelist.h"
0023 
0024 static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset);
0025 static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
0026 static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
0027 
0028 static void jffs2_erase_block(struct jffs2_sb_info *c,
0029                   struct jffs2_eraseblock *jeb)
0030 {
0031     int ret;
0032     uint32_t bad_offset;
0033 #ifdef __ECOS
0034        ret = jffs2_flash_erase(c, jeb);
0035        if (!ret) {
0036            jffs2_erase_succeeded(c, jeb);
0037            return;
0038        }
0039        bad_offset = jeb->offset;
0040 #else /* Linux */
0041     struct erase_info *instr;
0042 
0043     jffs2_dbg(1, "%s(): erase block %#08x (range %#08x-%#08x)\n",
0044           __func__,
0045           jeb->offset, jeb->offset, jeb->offset + c->sector_size);
0046     instr = kzalloc(sizeof(struct erase_info), GFP_KERNEL);
0047     if (!instr) {
0048         pr_warn("kzalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
0049         mutex_lock(&c->erase_free_sem);
0050         spin_lock(&c->erase_completion_lock);
0051         list_move(&jeb->list, &c->erase_pending_list);
0052         c->erasing_size -= c->sector_size;
0053         c->dirty_size += c->sector_size;
0054         jeb->dirty_size = c->sector_size;
0055         spin_unlock(&c->erase_completion_lock);
0056         mutex_unlock(&c->erase_free_sem);
0057         return;
0058     }
0059 
0060     instr->addr = jeb->offset;
0061     instr->len = c->sector_size;
0062 
0063     ret = mtd_erase(c->mtd, instr);
0064     if (!ret) {
0065         jffs2_erase_succeeded(c, jeb);
0066         kfree(instr);
0067         return;
0068     }
0069 
0070     bad_offset = instr->fail_addr;
0071     kfree(instr);
0072 #endif /* __ECOS */
0073 
0074     if (ret == -ENOMEM || ret == -EAGAIN) {
0075         /* Erase failed immediately. Refile it on the list */
0076         jffs2_dbg(1, "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n",
0077               jeb->offset, ret);
0078         mutex_lock(&c->erase_free_sem);
0079         spin_lock(&c->erase_completion_lock);
0080         list_move(&jeb->list, &c->erase_pending_list);
0081         c->erasing_size -= c->sector_size;
0082         c->dirty_size += c->sector_size;
0083         jeb->dirty_size = c->sector_size;
0084         spin_unlock(&c->erase_completion_lock);
0085         mutex_unlock(&c->erase_free_sem);
0086         return;
0087     }
0088 
0089     if (ret == -EROFS)
0090         pr_warn("Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n",
0091             jeb->offset);
0092     else
0093         pr_warn("Erase at 0x%08x failed immediately: errno %d\n",
0094             jeb->offset, ret);
0095 
0096     jffs2_erase_failed(c, jeb, bad_offset);
0097 }
0098 
0099 int jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
0100 {
0101     struct jffs2_eraseblock *jeb;
0102     int work_done = 0;
0103 
0104     mutex_lock(&c->erase_free_sem);
0105 
0106     spin_lock(&c->erase_completion_lock);
0107 
0108     while (!list_empty(&c->erase_complete_list) ||
0109            !list_empty(&c->erase_pending_list)) {
0110 
0111         if (!list_empty(&c->erase_complete_list)) {
0112             jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
0113             list_move(&jeb->list, &c->erase_checking_list);
0114             spin_unlock(&c->erase_completion_lock);
0115             mutex_unlock(&c->erase_free_sem);
0116             jffs2_mark_erased_block(c, jeb);
0117 
0118             work_done++;
0119             if (!--count) {
0120                 jffs2_dbg(1, "Count reached. jffs2_erase_pending_blocks leaving\n");
0121                 goto done;
0122             }
0123 
0124         } else if (!list_empty(&c->erase_pending_list)) {
0125             jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list);
0126             jffs2_dbg(1, "Starting erase of pending block 0x%08x\n",
0127                   jeb->offset);
0128             list_del(&jeb->list);
0129             c->erasing_size += c->sector_size;
0130             c->wasted_size -= jeb->wasted_size;
0131             c->free_size -= jeb->free_size;
0132             c->used_size -= jeb->used_size;
0133             c->dirty_size -= jeb->dirty_size;
0134             jeb->wasted_size = jeb->used_size = jeb->dirty_size = jeb->free_size = 0;
0135             jffs2_free_jeb_node_refs(c, jeb);
0136             list_add(&jeb->list, &c->erasing_list);
0137             spin_unlock(&c->erase_completion_lock);
0138             mutex_unlock(&c->erase_free_sem);
0139 
0140             jffs2_erase_block(c, jeb);
0141 
0142         } else {
0143             BUG();
0144         }
0145 
0146         /* Be nice */
0147         cond_resched();
0148         mutex_lock(&c->erase_free_sem);
0149         spin_lock(&c->erase_completion_lock);
0150     }
0151 
0152     spin_unlock(&c->erase_completion_lock);
0153     mutex_unlock(&c->erase_free_sem);
0154  done:
0155     jffs2_dbg(1, "jffs2_erase_pending_blocks completed\n");
0156     return work_done;
0157 }
0158 
0159 static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
0160 {
0161     jffs2_dbg(1, "Erase completed successfully at 0x%08x\n", jeb->offset);
0162     mutex_lock(&c->erase_free_sem);
0163     spin_lock(&c->erase_completion_lock);
0164     list_move_tail(&jeb->list, &c->erase_complete_list);
0165     /* Wake the GC thread to mark them clean */
0166     jffs2_garbage_collect_trigger(c);
0167     spin_unlock(&c->erase_completion_lock);
0168     mutex_unlock(&c->erase_free_sem);
0169     wake_up(&c->erase_wait);
0170 }
0171 
0172 static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset)
0173 {
0174     /* For NAND, if the failure did not occur at the device level for a
0175        specific physical page, don't bother updating the bad block table. */
0176     if (jffs2_cleanmarker_oob(c) && (bad_offset != (uint32_t)MTD_FAIL_ADDR_UNKNOWN)) {
0177         /* We had a device-level failure to erase.  Let's see if we've
0178            failed too many times. */
0179         if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) {
0180             /* We'd like to give this block another try. */
0181             mutex_lock(&c->erase_free_sem);
0182             spin_lock(&c->erase_completion_lock);
0183             list_move(&jeb->list, &c->erase_pending_list);
0184             c->erasing_size -= c->sector_size;
0185             c->dirty_size += c->sector_size;
0186             jeb->dirty_size = c->sector_size;
0187             spin_unlock(&c->erase_completion_lock);
0188             mutex_unlock(&c->erase_free_sem);
0189             return;
0190         }
0191     }
0192 
0193     mutex_lock(&c->erase_free_sem);
0194     spin_lock(&c->erase_completion_lock);
0195     c->erasing_size -= c->sector_size;
0196     c->bad_size += c->sector_size;
0197     list_move(&jeb->list, &c->bad_list);
0198     c->nr_erasing_blocks--;
0199     spin_unlock(&c->erase_completion_lock);
0200     mutex_unlock(&c->erase_free_sem);
0201     wake_up(&c->erase_wait);
0202 }
0203 
0204 /* Hmmm. Maybe we should accept the extra space it takes and make
0205    this a standard doubly-linked list? */
0206 static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
0207             struct jffs2_raw_node_ref *ref, struct jffs2_eraseblock *jeb)
0208 {
0209     struct jffs2_inode_cache *ic = NULL;
0210     struct jffs2_raw_node_ref **prev;
0211 
0212     prev = &ref->next_in_ino;
0213 
0214     /* Walk the inode's list once, removing any nodes from this eraseblock */
0215     while (1) {
0216         if (!(*prev)->next_in_ino) {
0217             /* We're looking at the jffs2_inode_cache, which is
0218                at the end of the linked list. Stash it and continue
0219                from the beginning of the list */
0220             ic = (struct jffs2_inode_cache *)(*prev);
0221             prev = &ic->nodes;
0222             continue;
0223         }
0224 
0225         if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
0226             /* It's in the block we're erasing */
0227             struct jffs2_raw_node_ref *this;
0228 
0229             this = *prev;
0230             *prev = this->next_in_ino;
0231             this->next_in_ino = NULL;
0232 
0233             if (this == ref)
0234                 break;
0235 
0236             continue;
0237         }
0238         /* Not to be deleted. Skip */
0239         prev = &((*prev)->next_in_ino);
0240     }
0241 
0242     /* PARANOIA */
0243     if (!ic) {
0244         JFFS2_WARNING("inode_cache/xattr_datum/xattr_ref"
0245                   " not found in remove_node_refs()!!\n");
0246         return;
0247     }
0248 
0249     jffs2_dbg(1, "Removed nodes in range 0x%08x-0x%08x from ino #%u\n",
0250           jeb->offset, jeb->offset + c->sector_size, ic->ino);
0251 
0252     D2({
0253         int i=0;
0254         struct jffs2_raw_node_ref *this;
0255         printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n");
0256 
0257         this = ic->nodes;
0258 
0259         printk(KERN_DEBUG);
0260         while(this) {
0261             pr_cont("0x%08x(%d)->",
0262                    ref_offset(this), ref_flags(this));
0263             if (++i == 5) {
0264                 printk(KERN_DEBUG);
0265                 i=0;
0266             }
0267             this = this->next_in_ino;
0268         }
0269         pr_cont("\n");
0270     });
0271 
0272     switch (ic->class) {
0273 #ifdef CONFIG_JFFS2_FS_XATTR
0274         case RAWNODE_CLASS_XATTR_DATUM:
0275             jffs2_release_xattr_datum(c, (struct jffs2_xattr_datum *)ic);
0276             break;
0277         case RAWNODE_CLASS_XATTR_REF:
0278             jffs2_release_xattr_ref(c, (struct jffs2_xattr_ref *)ic);
0279             break;
0280 #endif
0281         default:
0282             if (ic->nodes == (void *)ic && ic->pino_nlink == 0)
0283                 jffs2_del_ino_cache(c, ic);
0284     }
0285 }
0286 
0287 void jffs2_free_jeb_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
0288 {
0289     struct jffs2_raw_node_ref *block, *ref;
0290     jffs2_dbg(1, "Freeing all node refs for eraseblock offset 0x%08x\n",
0291           jeb->offset);
0292 
0293     block = ref = jeb->first_node;
0294 
0295     while (ref) {
0296         if (ref->flash_offset == REF_LINK_NODE) {
0297             ref = ref->next_in_ino;
0298             jffs2_free_refblock(block);
0299             block = ref;
0300             continue;
0301         }
0302         if (ref->flash_offset != REF_EMPTY_NODE && ref->next_in_ino)
0303             jffs2_remove_node_refs_from_ino_list(c, ref, jeb);
0304         /* else it was a non-inode node or already removed, so don't bother */
0305 
0306         ref++;
0307     }
0308     jeb->first_node = jeb->last_node = NULL;
0309 }
0310 
0311 static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t *bad_offset)
0312 {
0313     void *ebuf;
0314     uint32_t ofs;
0315     size_t retlen;
0316     int ret;
0317     unsigned long *wordebuf;
0318 
0319     ret = mtd_point(c->mtd, jeb->offset, c->sector_size, &retlen,
0320             &ebuf, NULL);
0321     if (ret != -EOPNOTSUPP) {
0322         if (ret) {
0323             jffs2_dbg(1, "MTD point failed %d\n", ret);
0324             goto do_flash_read;
0325         }
0326         if (retlen < c->sector_size) {
0327             /* Don't muck about if it won't let us point to the whole erase sector */
0328             jffs2_dbg(1, "MTD point returned len too short: 0x%zx\n",
0329                   retlen);
0330             mtd_unpoint(c->mtd, jeb->offset, retlen);
0331             goto do_flash_read;
0332         }
0333         wordebuf = ebuf-sizeof(*wordebuf);
0334         retlen /= sizeof(*wordebuf);
0335         do {
0336            if (*++wordebuf != ~0)
0337                break;
0338         } while(--retlen);
0339         mtd_unpoint(c->mtd, jeb->offset, c->sector_size);
0340         if (retlen) {
0341             pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08tx\n",
0342                 *wordebuf,
0343                 jeb->offset +
0344                 c->sector_size-retlen * sizeof(*wordebuf));
0345             return -EIO;
0346         }
0347         return 0;
0348     }
0349  do_flash_read:
0350     ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
0351     if (!ebuf) {
0352         pr_warn("Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n",
0353             jeb->offset);
0354         return -EAGAIN;
0355     }
0356 
0357     jffs2_dbg(1, "Verifying erase at 0x%08x\n", jeb->offset);
0358 
0359     for (ofs = jeb->offset; ofs < jeb->offset + c->sector_size; ) {
0360         uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
0361         int i;
0362 
0363         *bad_offset = ofs;
0364 
0365         ret = mtd_read(c->mtd, ofs, readlen, &retlen, ebuf);
0366         if (ret) {
0367             pr_warn("Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n",
0368                 ofs, ret);
0369             ret = -EIO;
0370             goto fail;
0371         }
0372         if (retlen != readlen) {
0373             pr_warn("Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n",
0374                 ofs, readlen, retlen);
0375             ret = -EIO;
0376             goto fail;
0377         }
0378         for (i=0; i<readlen; i += sizeof(unsigned long)) {
0379             /* It's OK. We know it's properly aligned */
0380             unsigned long *datum = ebuf + i;
0381             if (*datum + 1) {
0382                 *bad_offset += i;
0383                 pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08x\n",
0384                     *datum, *bad_offset);
0385                 ret = -EIO;
0386                 goto fail;
0387             }
0388         }
0389         ofs += readlen;
0390         cond_resched();
0391     }
0392     ret = 0;
0393 fail:
0394     kfree(ebuf);
0395     return ret;
0396 }
0397 
0398 static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
0399 {
0400     size_t retlen;
0401     int ret;
0402     uint32_t bad_offset;
0403 
0404     switch (jffs2_block_check_erase(c, jeb, &bad_offset)) {
0405     case -EAGAIN:   goto refile;
0406     case -EIO:  goto filebad;
0407     }
0408 
0409     /* Write the erase complete marker */
0410     jffs2_dbg(1, "Writing erased marker to block at 0x%08x\n", jeb->offset);
0411     bad_offset = jeb->offset;
0412 
0413     /* Cleanmarker in oob area or no cleanmarker at all ? */
0414     if (jffs2_cleanmarker_oob(c) || c->cleanmarker_size == 0) {
0415 
0416         if (jffs2_cleanmarker_oob(c)) {
0417             if (jffs2_write_nand_cleanmarker(c, jeb))
0418                 goto filebad;
0419         }
0420     } else {
0421 
0422         struct kvec vecs[1];
0423         struct jffs2_unknown_node marker = {
0424             .magic =    cpu_to_je16(JFFS2_MAGIC_BITMASK),
0425             .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
0426             .totlen =   cpu_to_je32(c->cleanmarker_size)
0427         };
0428 
0429         jffs2_prealloc_raw_node_refs(c, jeb, 1);
0430 
0431         marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
0432 
0433         vecs[0].iov_base = (unsigned char *) &marker;
0434         vecs[0].iov_len = sizeof(marker);
0435         ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
0436 
0437         if (ret || retlen != sizeof(marker)) {
0438             if (ret)
0439                 pr_warn("Write clean marker to block at 0x%08x failed: %d\n",
0440                        jeb->offset, ret);
0441             else
0442                 pr_warn("Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",
0443                        jeb->offset, sizeof(marker), retlen);
0444 
0445             goto filebad;
0446         }
0447     }
0448     /* Everything else got zeroed before the erase */
0449     jeb->free_size = c->sector_size;
0450 
0451     mutex_lock(&c->erase_free_sem);
0452     spin_lock(&c->erase_completion_lock);
0453 
0454     c->erasing_size -= c->sector_size;
0455     c->free_size += c->sector_size;
0456 
0457     /* Account for cleanmarker now, if it's in-band */
0458     if (c->cleanmarker_size && !jffs2_cleanmarker_oob(c))
0459         jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
0460 
0461     list_move_tail(&jeb->list, &c->free_list);
0462     c->nr_erasing_blocks--;
0463     c->nr_free_blocks++;
0464 
0465     jffs2_dbg_acct_sanity_check_nolock(c, jeb);
0466     jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
0467 
0468     spin_unlock(&c->erase_completion_lock);
0469     mutex_unlock(&c->erase_free_sem);
0470     wake_up(&c->erase_wait);
0471     return;
0472 
0473 filebad:
0474     jffs2_erase_failed(c, jeb, bad_offset);
0475     return;
0476 
0477 refile:
0478     /* Stick it back on the list from whence it came and come back later */
0479     mutex_lock(&c->erase_free_sem);
0480     spin_lock(&c->erase_completion_lock);
0481     jffs2_garbage_collect_trigger(c);
0482     list_move(&jeb->list, &c->erase_complete_list);
0483     spin_unlock(&c->erase_completion_lock);
0484     mutex_unlock(&c->erase_free_sem);
0485     return;
0486 }