The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/jffs2/scan.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * JFFS2 -- Journalling Flash File System, Version 2.
    3  *
    4  * Copyright (C) 2001 Red Hat, Inc.
    5  *
    6  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
    7  *
    8  * The original JFFS, from which the design for JFFS2 was derived,
    9  * was designed and implemented by Axis Communications AB.
   10  *
   11  * The contents of this file are subject to the Red Hat eCos Public
   12  * License Version 1.1 (the "Licence"); you may not use this file
   13  * except in compliance with the Licence.  You may obtain a copy of
   14  * the Licence at http://www.redhat.com/
   15  *
   16  * Software distributed under the Licence is distributed on an "AS IS"
   17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
   18  * See the Licence for the specific language governing rights and
   19  * limitations under the Licence.
   20  *
   21  * The Original Code is JFFS2 - Journalling Flash File System, version 2
   22  *
   23  * Alternatively, the contents of this file may be used under the
   24  * terms of the GNU General Public License version 2 (the "GPL"), in
   25  * which case the provisions of the GPL are applicable instead of the
   26  * above.  If you wish to allow the use of your version of this file
   27  * only under the terms of the GPL and not to allow others to use your
   28  * version of this file under the RHEPL, indicate your decision by
   29  * deleting the provisions above and replace them with the notice and
   30  * other provisions required by the GPL.  If you do not delete the
   31  * provisions above, a recipient may use your version of this file
   32  * under either the RHEPL or the GPL.
   33  *
   34  * $Id: scan.c,v 1.51.2.3 2002/07/25 20:49:06 dwmw2 Exp $
   35  *
   36  */
   37 #include <linux/kernel.h>
   38 #include <linux/slab.h>
   39 #include <linux/jffs2.h>
   40 #include <linux/mtd/mtd.h>
   41 #include <linux/pagemap.h>
   42 #include "nodelist.h"
   43 #include <linux/crc32.h>
   44 
   45 
   46 #define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
   47                 c->free_size -= _x; c->dirty_size += _x; \
   48                 jeb->free_size -= _x ; jeb->dirty_size += _x; \
   49                 }while(0)
   50 #define USED_SPACE(x) do { typeof(x) _x = (x); \
   51                 c->free_size -= _x; c->used_size += _x; \
   52                 jeb->free_size -= _x ; jeb->used_size += _x; \
   53                 }while(0)
   54 
   55 #define noisy_printk(noise, args...) do { \
   56         if (*(noise)) { \
   57                 printk(KERN_NOTICE args); \
   58                  (*(noise))--; \
   59                  if (!(*(noise))) { \
   60                          printk(KERN_NOTICE "Further such events for this erase block will not be printed\n"); \
   61                  } \
   62         } \
   63 } while(0)
   64 
   65 static uint32_t pseudo_random;
   66 static void jffs2_rotate_lists(struct jffs2_sb_info *c);
   67 
   68 static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
   69 
   70 /* These helper functions _must_ increase ofs and also do the dirty/used space accounting. 
   71  * Returning an error will abort the mount - bad checksums etc. should just mark the space
   72  * as dirty.
   73  */
   74 static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs, int *noise);
   75 static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
   76 static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
   77 
   78 
   79 int jffs2_scan_medium(struct jffs2_sb_info *c)
   80 {
   81         int i, ret;
   82         __u32 empty_blocks = 0;
   83 
   84         if (!c->blocks) {
   85                 printk(KERN_WARNING "EEEK! c->blocks is NULL!\n");
   86                 return -EINVAL;
   87         }
   88         for (i=0; i<c->nr_blocks; i++) {
   89                 struct jffs2_eraseblock *jeb = &c->blocks[i];
   90 
   91                 ret = jffs2_scan_eraseblock(c, jeb);
   92                 if (ret < 0)
   93                         return ret;
   94 
   95                 ACCT_PARANOIA_CHECK(jeb);
   96 
   97                 /* Now decide which list to put it on */
   98                 if (ret == 1) {
   99                         /* 
  100                          * Empty block.   Since we can't be sure it 
  101                          * was entirely erased, we just queue it for erase
  102                          * again.  It will be marked as such when the erase
  103                          * is complete.  Meanwhile we still count it as empty
  104                          * for later checks.
  105                          */
  106                         list_add(&jeb->list, &c->erase_pending_list);
  107                         empty_blocks++;
  108                         c->nr_erasing_blocks++;
  109                 } else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
  110                         /* Only a CLEANMARKER node is valid */
  111                         if (!jeb->dirty_size) {
  112                                 /* It's actually free */
  113                                 list_add(&jeb->list, &c->free_list);
  114                                 c->nr_free_blocks++;
  115                         } else {
  116                                 /* Dirt */
  117                                 D1(printk(KERN_DEBUG "Adding all-dirty block at 0x%08x to erase_pending_list\n", jeb->offset));
  118                                 list_add(&jeb->list, &c->erase_pending_list);
  119                                 c->nr_erasing_blocks++;
  120                         }
  121                 } else if (jeb->used_size > c->sector_size - (2*sizeof(struct jffs2_raw_inode))) {
  122                         /* Full (or almost full) of clean data. Clean list */
  123                         list_add(&jeb->list, &c->clean_list);
  124                 } else if (jeb->used_size) {
  125                         /* Some data, but not full. Dirty list. */
  126                         /* Except that we want to remember the block with most free space,
  127                            and stick it in the 'nextblock' position to start writing to it.
  128                            Later when we do snapshots, this must be the most recent block,
  129                            not the one with most free space.
  130                         */
  131                         if (jeb->free_size > 2*sizeof(struct jffs2_raw_inode) && 
  132                                 (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
  133                                 /* Better candidate for the next writes to go to */
  134                                 if (c->nextblock)
  135                                         list_add(&c->nextblock->list, &c->dirty_list);
  136                                 c->nextblock = jeb;
  137                         } else {
  138                                 list_add(&jeb->list, &c->dirty_list);
  139                         }
  140                 } else {
  141                         /* Nothing valid - not even a clean marker. Needs erasing. */
  142                         /* For now we just put it on the erasing list. We'll start the erases later */
  143                         printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset);
  144                         list_add(&jeb->list, &c->erase_pending_list);
  145                         c->nr_erasing_blocks++;
  146                 }
  147         }
  148         /* Rotate the lists by some number to ensure wear levelling */
  149         jffs2_rotate_lists(c);
  150 
  151         if (c->nr_erasing_blocks) {
  152                 if (!c->used_size && empty_blocks != c->nr_blocks) {
  153                         printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
  154                         return -EIO;
  155                 }
  156                 jffs2_erase_pending_trigger(c);
  157         }
  158         return 0;
  159 }
  160 
  161 static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) {
  162         struct jffs2_unknown_node node;
  163         __u32 ofs, prevofs;
  164         __u32 hdr_crc, nodetype;
  165         int err;
  166         int noise = 0;
  167 
  168         ofs = jeb->offset;
  169         prevofs = jeb->offset - 1;
  170 
  171         D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
  172 
  173         err = jffs2_scan_empty(c, jeb, &ofs, &noise);
  174         if (err) return err;
  175         if (ofs == jeb->offset + c->sector_size) {
  176                 D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
  177                 return 1;       /* special return code */
  178         }
  179         
  180         noise = 10;
  181 
  182         while(ofs < jeb->offset + c->sector_size) {
  183                 ssize_t retlen;
  184                 ACCT_PARANOIA_CHECK(jeb);
  185                 
  186                 if (ofs & 3) {
  187                         printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
  188                         ofs = (ofs+3)&~3;
  189                         continue;
  190                 }
  191                 if (ofs == prevofs) {
  192                         printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs);
  193                         DIRTY_SPACE(4);
  194                         ofs += 4;
  195                         continue;
  196                 }
  197                 prevofs = ofs;
  198                 
  199                 if (jeb->offset + c->sector_size < ofs + sizeof(node)) {
  200                         D1(printk(KERN_DEBUG "Fewer than %d bytes left to end of block. Not reading\n", sizeof(struct jffs2_unknown_node)));
  201                         DIRTY_SPACE((jeb->offset + c->sector_size)-ofs);
  202                         break;
  203                 }
  204 
  205                 err = c->mtd->read(c->mtd, ofs, sizeof(node), &retlen, (char *)&node);
  206                 
  207                 if (err) {
  208                         D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", sizeof(node), ofs, err));
  209                         return err;
  210                 }
  211                 if (retlen < sizeof(node)) {
  212                         D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%x bytes\n", ofs, retlen));
  213                         DIRTY_SPACE(retlen);
  214                         ofs += retlen;
  215                         continue;
  216                 }
  217 
  218                 if (node.magic == JFFS2_EMPTY_BITMASK && node.nodetype == JFFS2_EMPTY_BITMASK) {
  219                         D1(printk(KERN_DEBUG "Found empty flash at 0x%x\n", ofs));
  220                         err = jffs2_scan_empty(c, jeb, &ofs, &noise);
  221                         if (err) return err;
  222                         continue;
  223                 }
  224 
  225                 if (ofs == jeb->offset && node.magic == KSAMTIB_CIGAM_2SFFJ) {
  226                         printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);
  227                         DIRTY_SPACE(4);
  228                         ofs += 4;
  229                         continue;
  230                 }
  231                 if (node.magic == JFFS2_DIRTY_BITMASK) {
  232                         D1(printk(KERN_DEBUG "Empty bitmask at 0x%08x\n", ofs));
  233                         DIRTY_SPACE(4);
  234                         ofs += 4;
  235                         continue;
  236                 }
  237                 if (node.magic == JFFS2_OLD_MAGIC_BITMASK) {
  238                         printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);
  239                         printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");
  240                         DIRTY_SPACE(4);
  241                         ofs += 4;
  242                         continue;
  243                 }
  244                 if (node.magic != JFFS2_MAGIC_BITMASK) {
  245                         /* OK. We're out of possibilities. Whinge and move on */
  246                         noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, node.magic);
  247                         DIRTY_SPACE(4);
  248                         ofs += 4;
  249                         continue;
  250                 }
  251                 /* We seem to have a node of sorts. Check the CRC */
  252                 nodetype = node.nodetype;
  253                 node.nodetype |= JFFS2_NODE_ACCURATE;
  254                 hdr_crc = crc32(0, &node, sizeof(node)-4);
  255                 node.nodetype = nodetype;
  256                 if (hdr_crc != node.hdr_crc) {
  257                         noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
  258                                      ofs, node.magic, node.nodetype, node.totlen, node.hdr_crc, hdr_crc);
  259                         DIRTY_SPACE(4);
  260                         ofs += 4;
  261                         continue;
  262                 }
  263 
  264                 if (ofs + node.totlen > jeb->offset + c->sector_size) {
  265                         /* Eep. Node goes over the end of the erase block. */
  266                         printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
  267                                ofs, node.totlen);
  268                         printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");
  269                         DIRTY_SPACE(4);
  270                         ofs += 4;
  271                         continue;
  272                 }
  273 
  274                 switch(node.nodetype | JFFS2_NODE_ACCURATE) {
  275                 case JFFS2_NODETYPE_INODE:
  276                         err = jffs2_scan_inode_node(c, jeb, &ofs);
  277                         if (err) return err;
  278                         break;
  279                         
  280                 case JFFS2_NODETYPE_DIRENT:
  281                         err = jffs2_scan_dirent_node(c, jeb, &ofs);
  282                         if (err) return err;
  283                         break;
  284 
  285                 case JFFS2_NODETYPE_CLEANMARKER:
  286                         if (node.totlen != sizeof(struct jffs2_unknown_node)) {
  287                                 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", 
  288                                        ofs, node.totlen, sizeof(struct jffs2_unknown_node));
  289                                 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
  290                         } else if (jeb->first_node) {
  291                                 printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);
  292                                 DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
  293                                 ofs += PAD(sizeof(struct jffs2_unknown_node));
  294                                 continue;
  295                         } else {
  296                                 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
  297                                 if (!marker_ref) {
  298                                         printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n");
  299                                         return -ENOMEM;
  300                                 }
  301                                 marker_ref->next_in_ino = NULL;
  302                                 marker_ref->next_phys = NULL;
  303                                 marker_ref->flash_offset = ofs;
  304                                 marker_ref->totlen = sizeof(struct jffs2_unknown_node);
  305                                 jeb->first_node = jeb->last_node = marker_ref;
  306                              
  307                                 USED_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
  308                         }
  309                         ofs += PAD(sizeof(struct jffs2_unknown_node));
  310                         break;
  311 
  312                 default:
  313                         switch (node.nodetype & JFFS2_COMPAT_MASK) {
  314                         case JFFS2_FEATURE_ROCOMPAT:
  315                                 printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
  316                                 c->flags |= JFFS2_SB_FLAG_RO;
  317                                 if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY))
  318                                         return -EROFS;
  319                                 DIRTY_SPACE(PAD(node.totlen));
  320                                 ofs += PAD(node.totlen);
  321                                 continue;
  322 
  323                         case JFFS2_FEATURE_INCOMPAT:
  324                                 printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
  325                                 return -EINVAL;
  326 
  327                         case JFFS2_FEATURE_RWCOMPAT_DELETE:
  328                                 printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
  329                                 DIRTY_SPACE(PAD(node.totlen));
  330                                 ofs += PAD(node.totlen);
  331                                 break;
  332 
  333                         case JFFS2_FEATURE_RWCOMPAT_COPY:
  334                                 printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
  335                                 USED_SPACE(PAD(node.totlen));
  336                                 ofs += PAD(node.totlen);
  337                                 break;
  338                         }
  339                 }
  340         }
  341         D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, used 0x%08x\n", jeb->offset, 
  342                   jeb->free_size, jeb->dirty_size, jeb->used_size));
  343         return 0;
  344 }
  345 
  346 /* We're pointing at the first empty word on the flash. Scan and account for the whole dirty region */
  347 static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *startofs, int *noise)
  348 {
  349         __u32 *buf;
  350         __u32 scanlen = (jeb->offset + c->sector_size) - *startofs;
  351         __u32 curofs = *startofs;
  352         
  353         buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL);
  354         if (!buf) {
  355                 printk(KERN_WARNING "Scan buffer allocation failed\n");
  356                 return -ENOMEM;
  357         }
  358         while(scanlen) {
  359                 ssize_t retlen;
  360                 int ret, i;
  361                 
  362                 ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf);
  363                 if(ret) {
  364                         D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret));
  365                         kfree(buf);
  366                         return ret;
  367                 }
  368                 if (retlen < 4) {
  369                         D1(printk(KERN_WARNING "Eep. too few bytes read in scan_empty()\n"));
  370                         kfree(buf);
  371                         return -EIO;
  372                 }
  373                 for (i=0; i<(retlen / 4); i++) {
  374                         if (buf[i] != 0xffffffff) {
  375                                 curofs += i*4;
  376 
  377                                 noisy_printk(noise, "jffs2_scan_empty(): Empty block at 0x%08x ends at 0x%08x (with 0x%08x)! Marking dirty\n", *startofs, curofs, buf[i]);
  378                                 DIRTY_SPACE(curofs - (*startofs));
  379                                 *startofs = curofs;
  380                                 kfree(buf);
  381                                 return 0;
  382                         }
  383                 }
  384                 scanlen -= retlen&~3;
  385                 curofs += retlen&~3;
  386         }
  387 
  388         D1(printk(KERN_DEBUG "Empty flash detected from 0x%08x to 0x%08x\n", *startofs, curofs));
  389         kfree(buf);
  390         *startofs = curofs;
  391         return 0;
  392 }
  393 
  394 static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, __u32 ino)
  395 {
  396         struct jffs2_inode_cache *ic;
  397 
  398         ic = jffs2_get_ino_cache(c, ino);
  399         if (ic)
  400                 return ic;
  401 
  402         ic = jffs2_alloc_inode_cache();
  403         if (!ic) {
  404                 printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n");
  405                 return NULL;
  406         }
  407         memset(ic, 0, sizeof(*ic));
  408         ic->scan = kmalloc(sizeof(struct jffs2_scan_info), GFP_KERNEL);
  409         if (!ic->scan) {
  410                 printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of scan info for inode cache failed\n");
  411                 jffs2_free_inode_cache(ic);
  412                 return NULL;
  413         }
  414         memset(ic->scan, 0, sizeof(*ic->scan));
  415         ic->ino = ino;
  416         ic->nodes = (void *)ic;
  417         jffs2_add_ino_cache(c, ic);
  418         if (ino == 1)
  419                 ic->nlink=1;
  420         return ic;
  421 }
  422 
  423 static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
  424 {
  425         struct jffs2_raw_node_ref *raw;
  426         struct jffs2_full_dnode *fn;
  427         struct jffs2_tmp_dnode_info *tn, **tn_list;
  428         struct jffs2_inode_cache *ic;
  429         struct jffs2_raw_inode ri;
  430         __u32 crc;
  431         __u16 oldnodetype;
  432         int ret;
  433         ssize_t retlen;
  434 
  435         D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", *ofs));
  436 
  437         ret = c->mtd->read(c->mtd, *ofs, sizeof(ri), &retlen, (char *)&ri);
  438         if (ret) {
  439                 printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs, ret);
  440                 return ret;
  441         }
  442         if (retlen != sizeof(ri)) {
  443                 printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 
  444                        retlen, *ofs, sizeof(ri));
  445                 return -EIO;
  446         }
  447 
  448         /* We sort of assume that the node was accurate when it was 
  449            first written to the medium :) */
  450         oldnodetype = ri.nodetype;
  451         ri.nodetype |= JFFS2_NODE_ACCURATE;
  452         crc = crc32(0, &ri, sizeof(ri)-8);
  453         ri.nodetype = oldnodetype;
  454 
  455         if(crc != ri.node_crc) {
  456                 printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
  457                        *ofs, ri.node_crc, crc);
  458                 /* FIXME: Why do we believe totlen? */
  459                 DIRTY_SPACE(4);
  460                 *ofs += 4;
  461                 return 0;
  462         }
  463         /* There was a bug where we wrote hole nodes out with csize/dsize
  464            swapped. Deal with it */
  465         if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) {
  466                 ri.dsize = ri.csize;
  467                 ri.csize = 0;
  468         }
  469 
  470         if (ri.csize) {
  471                 /* Check data CRC too */
  472                 unsigned char *dbuf;
  473                 __u32 crc;
  474 
  475                 dbuf = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
  476                 if (!dbuf) {
  477                         printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of temporary data buffer for CRC check failed\n");
  478                         return -ENOMEM;
  479                 }
  480                 ret = c->mtd->read(c->mtd, *ofs+sizeof(ri), ri.csize, &retlen, dbuf);
  481                 if (ret) {
  482                         printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs+sizeof(ri), ret);
  483                         kfree(dbuf);
  484                         return ret;
  485                 }
  486                 if (retlen != ri.csize) {
  487                         printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 
  488                                retlen, *ofs+ sizeof(ri), ri.csize);
  489                         kfree(dbuf);
  490                         return -EIO;
  491                 }
  492                 crc = crc32(0, dbuf, ri.csize);
  493                 kfree(dbuf);
  494                 if (crc != ri.data_crc) {
  495                         printk(KERN_NOTICE "jffs2_scan_inode_node(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
  496                                *ofs, ri.data_crc, crc);
  497                         DIRTY_SPACE(PAD(ri.totlen));
  498                         *ofs += PAD(ri.totlen);
  499                         return 0;
  500                 }
  501         }
  502 
  503         /* Wheee. It worked */
  504         raw = jffs2_alloc_raw_node_ref();
  505         if (!raw) {
  506                 printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");
  507                 return -ENOMEM;
  508         }
  509         tn = jffs2_alloc_tmp_dnode_info();
  510         if (!tn) {
  511                 jffs2_free_raw_node_ref(raw);
  512                 return -ENOMEM;
  513         }
  514         fn = jffs2_alloc_full_dnode();
  515         if (!fn) {
  516                 jffs2_free_tmp_dnode_info(tn);
  517                 jffs2_free_raw_node_ref(raw);
  518                 return -ENOMEM;
  519         }
  520         ic = jffs2_scan_make_ino_cache(c, ri.ino);
  521         if (!ic) {
  522                 jffs2_free_full_dnode(fn);
  523                 jffs2_free_tmp_dnode_info(tn);
  524                 jffs2_free_raw_node_ref(raw);
  525                 return -ENOMEM;
  526         }
  527 
  528         /* Build the data structures and file them for later */
  529         raw->flash_offset = *ofs;
  530         raw->totlen = PAD(ri.totlen);
  531         raw->next_phys = NULL;
  532         raw->next_in_ino = ic->nodes;
  533         ic->nodes = raw;
  534         if (!jeb->first_node)
  535                 jeb->first_node = raw;
  536         if (jeb->last_node)
  537                 jeb->last_node->next_phys = raw;
  538         jeb->last_node = raw;
  539 
  540         D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", 
  541                   ri.ino, ri.version, ri.offset, ri.offset+ri.dsize));
  542 
  543         pseudo_random += ri.version;
  544 
  545         for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) {
  546                 if ((*tn_list)->version < ri.version)
  547                         continue;
  548                 if ((*tn_list)->version > ri.version) 
  549                         break;
  550                 /* Wheee. We've found another instance of the same version number.
  551                    We should obsolete one of them. 
  552                 */
  553                 D1(printk(KERN_DEBUG "Duplicate version %d found in ino #%u. Previous one is at 0x%08x\n", ri.version, ic->ino, (*tn_list)->fn->raw->flash_offset &~3));
  554                 if (!jeb->used_size) {
  555                         D1(printk(KERN_DEBUG "No valid nodes yet found in this eraseblock 0x%08x, so obsoleting the new instance at 0x%08x\n", 
  556                                   jeb->offset, raw->flash_offset & ~3));
  557                         ri.nodetype &= ~JFFS2_NODE_ACCURATE;
  558                         /* Perhaps we could also mark it as such on the medium. Maybe later */
  559                 }
  560                 break;
  561         }
  562 
  563         if (ri.nodetype & JFFS2_NODE_ACCURATE) {
  564                 memset(fn,0,sizeof(*fn));
  565 
  566                 fn->ofs = ri.offset;
  567                 fn->size = ri.dsize;
  568                 fn->frags = 0;
  569                 fn->raw = raw;
  570 
  571                 tn->next = NULL;
  572                 tn->fn = fn;
  573                 tn->version = ri.version;
  574 
  575                 USED_SPACE(PAD(ri.totlen));
  576                 jffs2_add_tn_to_list(tn, &ic->scan->tmpnodes);
  577                 /* Make sure the one we just added is the _last_ in the list
  578                    with this version number, so the older ones get obsoleted */
  579                 while (tn->next && tn->next->version == tn->version) {
  580 
  581                         D1(printk(KERN_DEBUG "Shifting new node at 0x%08x after other node at 0x%08x for version %d in list\n",
  582                                   fn->raw->flash_offset&~3, tn->next->fn->raw->flash_offset &~3, ri.version));
  583 
  584                         if(tn->fn != fn)
  585                                 BUG();
  586                         tn->fn = tn->next->fn;
  587                         tn->next->fn = fn;
  588                         tn = tn->next;
  589                 }
  590         } else {
  591                 jffs2_free_full_dnode(fn);
  592                 jffs2_free_tmp_dnode_info(tn);
  593                 raw->flash_offset |= 1;
  594                 DIRTY_SPACE(PAD(ri.totlen));
  595         }               
  596         *ofs += PAD(ri.totlen);
  597         return 0;
  598 }
  599 
  600 static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
  601 {
  602         struct jffs2_raw_node_ref *raw;
  603         struct jffs2_full_dirent *fd;
  604         struct jffs2_inode_cache *ic;
  605         struct jffs2_raw_dirent rd;
  606         __u16 oldnodetype;
  607         int ret;
  608         __u32 crc;
  609         ssize_t retlen;
  610 
  611         D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", *ofs));
  612 
  613         ret = c->mtd->read(c->mtd, *ofs, sizeof(rd), &retlen, (char *)&rd);
  614         if (ret) {
  615                 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", *ofs, ret);
  616                 return ret;
  617         }
  618         if (retlen != sizeof(rd)) {
  619                 printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 
  620                        retlen, *ofs, sizeof(rd));
  621                 return -EIO;
  622         }
  623 
  624         /* We sort of assume that the node was accurate when it was 
  625            first written to the medium :) */
  626         oldnodetype = rd.nodetype;
  627         rd.nodetype |= JFFS2_NODE_ACCURATE;
  628         crc = crc32(0, &rd, sizeof(rd)-8);
  629         rd.nodetype = oldnodetype;
  630 
  631         if (crc != rd.node_crc) {
  632                 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
  633                        *ofs, rd.node_crc, crc);
  634                 /* FIXME: Why do we believe totlen? */
  635                 DIRTY_SPACE(4);
  636                 *ofs += 4;
  637                 return 0;
  638         }
  639 
  640         pseudo_random += rd.version;
  641 
  642         fd = jffs2_alloc_full_dirent(rd.nsize+1);
  643         if (!fd) {
  644                 return -ENOMEM;
  645 }
  646         ret = c->mtd->read(c->mtd, *ofs + sizeof(rd), rd.nsize, &retlen, &fd->name[0]);
  647         if (ret) {
  648                 jffs2_free_full_dirent(fd);
  649                 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", 
  650                        *ofs + sizeof(rd), ret);
  651                 return ret;
  652         }
  653         if (retlen != rd.nsize) {
  654                 jffs2_free_full_dirent(fd);
  655                 printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 
  656                        retlen, *ofs + sizeof(rd), rd.nsize);
  657                 return -EIO;
  658         }
  659         crc = crc32(0, fd->name, rd.nsize);
  660         if (crc != rd.name_crc) {
  661                 printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
  662                        *ofs, rd.name_crc, crc); 
  663                 fd->name[rd.nsize]=0;
  664                 D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));
  665                 jffs2_free_full_dirent(fd);
  666                 /* FIXME: Why do we believe totlen? */
  667                 DIRTY_SPACE(PAD(rd.totlen));
  668                 *ofs += PAD(rd.totlen);
  669                 return 0;
  670         }
  671         raw = jffs2_alloc_raw_node_ref();
  672         if (!raw) {
  673                 jffs2_free_full_dirent(fd);
  674                 printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");
  675                 return -ENOMEM;
  676         }
  677         ic = jffs2_scan_make_ino_cache(c, rd.pino);
  678         if (!ic) {
  679                 jffs2_free_full_dirent(fd);
  680                 jffs2_free_raw_node_ref(raw);
  681                 return -ENOMEM;
  682         }
  683         
  684         raw->totlen = PAD(rd.totlen);
  685         raw->flash_offset = *ofs;
  686         raw->next_phys = NULL;
  687         raw->next_in_ino = ic->nodes;
  688         ic->nodes = raw;
  689         if (!jeb->first_node)
  690                 jeb->first_node = raw;
  691         if (jeb->last_node)
  692                 jeb->last_node->next_phys = raw;
  693         jeb->last_node = raw;
  694 
  695         if (rd.nodetype & JFFS2_NODE_ACCURATE) {
  696                 fd->raw = raw;
  697                 fd->next = NULL;
  698                 fd->version = rd.version;
  699                 fd->ino = rd.ino;
  700                 fd->name[rd.nsize]=0;
  701                 fd->nhash = full_name_hash(fd->name, rd.nsize);
  702                 fd->type = rd.type;
  703 
  704                 USED_SPACE(PAD(rd.totlen));
  705                 jffs2_add_fd_to_list(c, fd, &ic->scan->dents);
  706         } else {
  707                 raw->flash_offset |= 1;
  708                 jffs2_free_full_dirent(fd);
  709 
  710                 DIRTY_SPACE(PAD(rd.totlen));
  711         } 
  712         *ofs += PAD(rd.totlen);
  713         return 0;
  714 }
  715 
  716 static int count_list(struct list_head *l)
  717 {
  718         uint32_t count = 0;
  719         struct list_head *tmp;
  720 
  721         list_for_each(tmp, l) {
  722                 count++;
  723         }
  724         return count;
  725 }
  726 
  727 /* Note: This breaks if list_empty(head). I don't care. You
  728    might, if you copy this code and use it elsewhere :) */
  729 static void rotate_list(struct list_head *head, uint32_t count)
  730 {
  731         struct list_head *n = head->next;
  732 
  733         list_del(head);
  734         while(count--)
  735                 n = n->next;
  736         list_add(head, n);
  737 }
  738 
  739 static void jffs2_rotate_lists(struct jffs2_sb_info *c)
  740 {
  741         uint32_t x;
  742 
  743         x = count_list(&c->clean_list);
  744         if (x)
  745                 rotate_list((&c->clean_list), pseudo_random % x);
  746 
  747         x = count_list(&c->dirty_list);
  748         if (x)
  749                 rotate_list((&c->dirty_list), pseudo_random % x);
  750 
  751         if (c->nr_erasing_blocks)
  752                 rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks);
  753 
  754         if (c->nr_free_blocks) /* Not that it should ever be zero */
  755                 rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks);
  756 }

Cache object: 09d02bf10bf784f669f0483f40ef5098


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.