⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (crc != je32_to_cpu(rr->node_crc)) {		JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",			      ofs, je32_to_cpu(rr->node_crc), crc);		if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen)))))			return err;		return 0;	}	if (PAD(sizeof(struct jffs2_raw_xref)) != je32_to_cpu(rr->totlen)) {		JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%zd\n",			      ofs, je32_to_cpu(rr->totlen),			      PAD(sizeof(struct jffs2_raw_xref)));		if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rr->totlen))))			return err;		return 0;	}	ref = jffs2_alloc_xattr_ref();	if (!ref)		return -ENOMEM;	/* BEFORE jffs2_build_xattr_subsystem() called, 	 * and AFTER xattr_ref is marked as a dead xref,	 * ref->xid is used to store 32bit xid, xd is not used	 * ref->ino is used to store 32bit inode-number, ic is not used	 * Thoes variables are declared as union, thus using those	 * are exclusive. In a similar way, ref->next is temporarily	 * used to chain all xattr_ref object. It's re-chained to	 * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly.	 */	ref->ino = je32_to_cpu(rr->ino);	ref->xid = je32_to_cpu(rr->xid);	ref->xseqno = je32_to_cpu(rr->xseqno);	if (ref->xseqno > c->highest_xseqno)		c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);	ref->next = c->xref_temp;	c->xref_temp = ref;	jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), (void *)ref);	if (jffs2_sum_active())		jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset);	dbg_xattr("scan xref at %#08x (xid=%u, ino=%u)\n",		  ofs, ref->xid, ref->ino);	return 0;}#endif/* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into   the flash, XIP-style */static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,				  unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {	struct jffs2_unknown_node *node;	struct jffs2_unknown_node crcnode;	uint32_t ofs, prevofs;	uint32_t hdr_crc, buf_ofs, buf_len;	int err;	int noise = 0;#ifdef CONFIG_JFFS2_FS_WRITEBUFFER	int cleanmarkerfound = 0;#endif	ofs = jeb->offset;	prevofs = jeb->offset - 1;	D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));#ifdef CONFIG_JFFS2_FS_WRITEBUFFER	if (jffs2_cleanmarker_oob(c)) {		int ret;		if (c->mtd->block_isbad(c->mtd, jeb->offset))			return BLK_STATE_BADBLOCK;		ret = jffs2_check_nand_cleanmarker(c, jeb);		D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));		/* Even if it's not found, we still scan to see		   if the block is empty. We use this information		   to decide whether to erase it or not. */		switch (ret) {		case 0:		cleanmarkerfound = 1; break;		case 1: 	break;		default: 	return ret;		}	}#endif	if (jffs2_sum_active()) {		struct jffs2_sum_marker *sm;		void *sumptr = NULL;		uint32_t sumlen;	      		if (!buf_size) {			/* XIP case. Just look, point at the summary if it's there */			sm = (void *)buf + c->sector_size - sizeof(*sm);			if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) {				sumptr = buf + je32_to_cpu(sm->offset);				sumlen = c->sector_size - je32_to_cpu(sm->offset);			}		} else {			/* If NAND flash, read a whole page of it. Else just the end */			if (c->wbuf_pagesize)				buf_len = c->wbuf_pagesize;			else				buf_len = sizeof(*sm);			/* Read as much as we want into the _end_ of the preallocated buffer */			err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, 						  jeb->offset + c->sector_size - buf_len,						  buf_len);							if (err)				return err;			sm = (void *)buf + buf_size - sizeof(*sm);			if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) {				sumlen = c->sector_size - je32_to_cpu(sm->offset);				sumptr = buf + buf_size - sumlen;				/* Now, make sure the summary itself is available */				if (sumlen > buf_size) {					/* Need to kmalloc for this. */					sumptr = kmalloc(sumlen, GFP_KERNEL);					if (!sumptr)						return -ENOMEM;					memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len);				}				if (buf_len < sumlen) {					/* Need to read more so that the entire summary node is present */					err = jffs2_fill_scan_buf(c, sumptr, 								  jeb->offset + c->sector_size - sumlen,								  sumlen - buf_len);									if (err)						return err;				}			}		}		if (sumptr) {			err = jffs2_sum_scan_sumnode(c, jeb, sumptr, sumlen, &pseudo_random);			if (buf_size && sumlen > buf_size)				kfree(sumptr);			/* If it returns with a real error, bail. 			   If it returns positive, that's a block classification			   (i.e. BLK_STATE_xxx) so return that too.			   If it returns zero, fall through to full scan. */			if (err)				return err;		}	}	buf_ofs = jeb->offset;	if (!buf_size) {		/* This is the XIP case -- we're reading _directly_ from the flash chip */		buf_len = c->sector_size;	} else {		buf_len = EMPTY_SCAN_SIZE(c->sector_size);		err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);		if (err)			return err;	}	/* We temporarily use 'ofs' as a pointer into the buffer/jeb */	ofs = 0;	/* Scan only 4KiB of 0xFF before declaring it's empty */	while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)		ofs += 4;	if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {#ifdef CONFIG_JFFS2_FS_WRITEBUFFER		if (jffs2_cleanmarker_oob(c)) {			/* scan oob, take care of cleanmarker */			int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);			D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret));			switch (ret) {			case 0:		return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF;			case 1: 	return BLK_STATE_ALLDIRTY;			default: 	return ret;			}		}#endif		D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));		if (c->cleanmarker_size == 0)			return BLK_STATE_CLEANMARKER;	/* don't bother with re-erase */		else			return BLK_STATE_ALLFF;	/* OK to erase if all blocks are like this */	}	if (ofs) {		D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,			  jeb->offset + ofs));		if ((err = jffs2_prealloc_raw_node_refs(c, jeb, 1)))			return err;		if ((err = jffs2_scan_dirty_space(c, jeb, ofs)))			return err;	}	/* Now ofs is a complete physical flash offset as it always was... */	ofs += jeb->offset;	noise = 10;	dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);scan_more:	while(ofs < jeb->offset + c->sector_size) {		jffs2_dbg_acct_paranoia_check_nolock(c, jeb);		/* Make sure there are node refs available for use */		err = jffs2_prealloc_raw_node_refs(c, jeb, 2);		if (err)			return err;		cond_resched();		if (ofs & 3) {			printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);			ofs = PAD(ofs);			continue;		}		if (ofs == prevofs) {			printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs);			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))				return err;			ofs += 4;			continue;		}		prevofs = ofs;		if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {			D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node),				  jeb->offset, c->sector_size, ofs, sizeof(*node)));			if ((err = jffs2_scan_dirty_space(c, jeb, (jeb->offset + c->sector_size)-ofs)))				return err;			break;		}		if (buf_ofs + buf_len < ofs + sizeof(*node)) {			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);			D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n",				  sizeof(struct jffs2_unknown_node), buf_len, ofs));			err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);			if (err)				return err;			buf_ofs = ofs;		}		node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs];		if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {			uint32_t inbuf_ofs;			uint32_t empty_start, scan_end;			empty_start = ofs;			ofs += 4;			scan_end = min_t(uint32_t, EMPTY_SCAN_SIZE(c->sector_size)/8, buf_len);			D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs));		more_empty:			inbuf_ofs = ofs - buf_ofs;			while (inbuf_ofs < scan_end) {				if (unlikely(*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)) {					printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",					       empty_start, ofs);					if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start)))						return err;					goto scan_more;				}				inbuf_ofs+=4;				ofs += 4;			}			/* Ran off end. */			D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs));			/* If we're only checking the beginning of a block with a cleanmarker,			   bail now */			if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&			    c->cleanmarker_size && !jeb->dirty_size && !ref_next(jeb->first_node)) {				D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));				return BLK_STATE_CLEANMARKER;			}			if (!buf_size && (scan_end != buf_len)) {/* XIP/point case */				scan_end = buf_len;				goto more_empty;			}						/* See how much more there is to read in this eraseblock... */			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);			if (!buf_len) {				/* No more to read. Break out of main loop without marking				   this range of empty space as dirty (because it's not) */				D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",					  empty_start));				break;			}			/* point never reaches here */			scan_end = buf_len;			D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs));			err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);			if (err)				return err;			buf_ofs = ofs;			goto more_empty;		}		if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {			printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))				return err;			ofs += 4;			continue;		}		if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {			D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))				return err;			ofs += 4;			continue;		}		if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) {			printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);			printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))				return err;			ofs += 4;			continue;		}		if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {			/* OK. We're out of possibilities. Whinge and move on */			noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",				     JFFS2_MAGIC_BITMASK, ofs,				     je16_to_cpu(node->magic));			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))				return err;			ofs += 4;			continue;		}		/* We seem to have a node of sorts. Check the CRC */		crcnode.magic = node->magic;		crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE);		crcnode.totlen = node->totlen;		hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4);		if (hdr_crc != je32_to_cpu(node->hdr_crc)) {			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",				     ofs, je16_to_cpu(node->magic),				     je16_to_cpu(node->nodetype),				     je32_to_cpu(node->totlen),				     je32_to_cpu(node->hdr_crc),				     hdr_crc);			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))				return err;			ofs += 4;			continue;		}		if (ofs + je32_to_cpu(node->totlen) > jeb->offset + c->sector_size) {			/* Eep. Node goes over the end of the erase block. */			printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",			       ofs, je32_to_cpu(node->totlen));			printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))				return err;			ofs += 4;			continue;		}		if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) {			/* Wheee. This is an obsoleted node */			D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs));			if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))				return err;			ofs += PAD(je32_to_cpu(node->totlen));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -