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

📄 summary.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			case JFFS2_NODETYPE_DIRENT: {				struct jffs2_sum_dirent_flash *spd;				int checkedlen;				spd = sp;				dbg_summary("Dirent at 0x%08x-0x%08x\n",					    jeb->offset + je32_to_cpu(spd->offset),					    jeb->offset + je32_to_cpu(spd->offset) + je32_to_cpu(spd->totlen));				/* This should never happen, but https://dev.laptop.org/ticket/4184 */				checkedlen = strnlen(spd->name, spd->nsize);				if (!checkedlen) {					printk(KERN_ERR "Dirent at %08x has zero at start of name. Aborting mount.\n",					       jeb->offset + je32_to_cpu(spd->offset));					return -EIO;				}				if (checkedlen < spd->nsize) {					printk(KERN_ERR "Dirent at %08x has zeroes in name. Truncating to %d chars\n",					       jeb->offset + je32_to_cpu(spd->offset), checkedlen);				}				fd = jffs2_alloc_full_dirent(checkedlen+1);				if (!fd)					return -ENOMEM;				memcpy(&fd->name, spd->name, checkedlen);				fd->name[checkedlen] = 0;				ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino));				if (!ic) {					jffs2_free_full_dirent(fd);					return -ENOMEM;				}				fd->raw = sum_link_node_ref(c, jeb,  je32_to_cpu(spd->offset) | REF_UNCHECKED,							    PAD(je32_to_cpu(spd->totlen)), ic);				fd->next = NULL;				fd->version = je32_to_cpu(spd->version);				fd->ino = je32_to_cpu(spd->ino);				fd->nhash = full_name_hash(fd->name, checkedlen);				fd->type = spd->type;				jffs2_add_fd_to_list(c, fd, &ic->scan_dents);				*pseudo_random += je32_to_cpu(spd->version);				sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize);				break;			}#ifdef CONFIG_JFFS2_FS_XATTR			case JFFS2_NODETYPE_XATTR: {				struct jffs2_xattr_datum *xd;				struct jffs2_sum_xattr_flash *spx;				spx = (struct jffs2_sum_xattr_flash *)sp;				dbg_summary("xattr at %#08x-%#08x (xid=%u, version=%u)\n", 					    jeb->offset + je32_to_cpu(spx->offset),					    jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen),					    je32_to_cpu(spx->xid), je32_to_cpu(spx->version));				xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),								je32_to_cpu(spx->version));				if (IS_ERR(xd))					return PTR_ERR(xd);				if (xd->version > je32_to_cpu(spx->version)) {					/* node is not the newest one */					struct jffs2_raw_node_ref *raw						= sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,								    PAD(je32_to_cpu(spx->totlen)), NULL);					raw->next_in_ino = xd->node->next_in_ino;					xd->node->next_in_ino = raw;				} else {					xd->version = je32_to_cpu(spx->version);					sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,							  PAD(je32_to_cpu(spx->totlen)), (void *)xd);				}				*pseudo_random += je32_to_cpu(spx->xid);				sp += JFFS2_SUMMARY_XATTR_SIZE;				break;			}			case JFFS2_NODETYPE_XREF: {				struct jffs2_xattr_ref *ref;				struct jffs2_sum_xref_flash *spr;				spr = (struct jffs2_sum_xref_flash *)sp;				dbg_summary("xref at %#08x-%#08x\n",					    jeb->offset + je32_to_cpu(spr->offset),					    jeb->offset + je32_to_cpu(spr->offset) + 					    (uint32_t)PAD(sizeof(struct jffs2_raw_xref)));				ref = jffs2_alloc_xattr_ref();				if (!ref) {					JFFS2_NOTICE("allocation of xattr_datum failed\n");					return -ENOMEM;				}				ref->next = c->xref_temp;				c->xref_temp = ref;				sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED,						  PAD(sizeof(struct jffs2_raw_xref)), (void *)ref);				*pseudo_random += ref->node->flash_offset;				sp += JFFS2_SUMMARY_XREF_SIZE;				break;			}#endif			default : {				uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype);				JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype);				if ((nodetype & JFFS2_COMPAT_MASK) == JFFS2_FEATURE_INCOMPAT)					return -EIO;				/* For compatible node types, just fall back to the full scan */				c->wasted_size -= jeb->wasted_size;				c->free_size += c->sector_size - jeb->free_size;				c->used_size -= jeb->used_size;				c->dirty_size -= jeb->dirty_size;				jeb->wasted_size = jeb->used_size = jeb->dirty_size = 0;				jeb->free_size = c->sector_size;				jffs2_free_jeb_node_refs(c, jeb);				return -ENOTRECOVERABLE;			}		}	}	return 0;}/* Process the summary node - called from jffs2_scan_eraseblock() */int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,			   struct jffs2_raw_summary *summary, uint32_t sumsize,			   uint32_t *pseudo_random){	struct jffs2_unknown_node crcnode;	int ret, ofs;	uint32_t crc;	ofs = c->sector_size - sumsize;	dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",		    jeb->offset, jeb->offset + ofs, sumsize);	/* OK, now check for node validity and CRC */	crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);	crcnode.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);	crcnode.totlen = summary->totlen;	crc = crc32(0, &crcnode, sizeof(crcnode)-4);	if (je32_to_cpu(summary->hdr_crc) != crc) {		dbg_summary("Summary node header is corrupt (bad CRC or "				"no summary at all)\n");		goto crc_err;	}	if (je32_to_cpu(summary->totlen) != sumsize) {		dbg_summary("Summary node is corrupt (wrong erasesize?)\n");		goto crc_err;	}	crc = crc32(0, summary, sizeof(struct jffs2_raw_summary)-8);	if (je32_to_cpu(summary->node_crc) != crc) {		dbg_summary("Summary node is corrupt (bad CRC)\n");		goto crc_err;	}	crc = crc32(0, summary->sum, sumsize - sizeof(struct jffs2_raw_summary));	if (je32_to_cpu(summary->sum_crc) != crc) {		dbg_summary("Summary node data is corrupt (bad CRC)\n");		goto crc_err;	}	if ( je32_to_cpu(summary->cln_mkr) ) {		dbg_summary("Summary : CLEANMARKER node \n");		ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);		if (ret)			return ret;		if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) {			dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n",				je32_to_cpu(summary->cln_mkr), c->cleanmarker_size);			if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))				return ret;		} else if (jeb->first_node) {			dbg_summary("CLEANMARKER node not first node in block "					"(0x%08x)\n", jeb->offset);			if ((ret = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))				return ret;		} else {			jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL,					    je32_to_cpu(summary->cln_mkr), NULL);		}	}	ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);	/* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full	   scan of this eraseblock. So return zero */	if (ret == -ENOTRECOVERABLE)		return 0;	if (ret)		return ret;		/* real error */	/* for PARANOIA_CHECK */	ret = jffs2_prealloc_raw_node_refs(c, jeb, 2);	if (ret)		return ret;	sum_link_node_ref(c, jeb, ofs | REF_NORMAL, sumsize, NULL);	if (unlikely(jeb->free_size)) {		JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n",			      jeb->free_size, jeb->offset);		jeb->wasted_size += jeb->free_size;		c->wasted_size += jeb->free_size;		c->free_size -= jeb->free_size;		jeb->free_size = 0;	}	return jffs2_scan_classify_jeb(c, jeb);crc_err:	JFFS2_WARNING("Summary node crc error, skipping summary information.\n");	return 0;}/* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,					uint32_t infosize, uint32_t datasize, int padsize){	struct jffs2_raw_summary isum;	union jffs2_sum_mem *temp;	struct jffs2_sum_marker *sm;	struct kvec vecs[2];	uint32_t sum_ofs;	void *wpage;	int ret;	size_t retlen;	memset(c->summary->sum_buf, 0xff, datasize);	memset(&isum, 0, sizeof(isum));	isum.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);	isum.nodetype = cpu_to_je16(JFFS2_NODETYPE_SUMMARY);	isum.totlen = cpu_to_je32(infosize);	isum.hdr_crc = cpu_to_je32(crc32(0, &isum, sizeof(struct jffs2_unknown_node) - 4));	isum.padded = cpu_to_je32(c->summary->sum_padded);	isum.cln_mkr = cpu_to_je32(c->cleanmarker_size);	isum.sum_num = cpu_to_je32(c->summary->sum_num);	wpage = c->summary->sum_buf;	while (c->summary->sum_num) {		temp = c->summary->sum_list_head;		switch (je16_to_cpu(temp->u.nodetype)) {			case JFFS2_NODETYPE_INODE: {				struct jffs2_sum_inode_flash *sino_ptr = wpage;				sino_ptr->nodetype = temp->i.nodetype;				sino_ptr->inode = temp->i.inode;				sino_ptr->version = temp->i.version;				sino_ptr->offset = temp->i.offset;				sino_ptr->totlen = temp->i.totlen;				wpage += JFFS2_SUMMARY_INODE_SIZE;				break;			}			case JFFS2_NODETYPE_DIRENT: {				struct jffs2_sum_dirent_flash *sdrnt_ptr = wpage;				sdrnt_ptr->nodetype = temp->d.nodetype;				sdrnt_ptr->totlen = temp->d.totlen;				sdrnt_ptr->offset = temp->d.offset;				sdrnt_ptr->pino = temp->d.pino;				sdrnt_ptr->version = temp->d.version;				sdrnt_ptr->ino = temp->d.ino;				sdrnt_ptr->nsize = temp->d.nsize;				sdrnt_ptr->type = temp->d.type;				memcpy(sdrnt_ptr->name, temp->d.name,							temp->d.nsize);				wpage += JFFS2_SUMMARY_DIRENT_SIZE(temp->d.nsize);				break;			}#ifdef CONFIG_JFFS2_FS_XATTR			case JFFS2_NODETYPE_XATTR: {				struct jffs2_sum_xattr_flash *sxattr_ptr = wpage;				temp = c->summary->sum_list_head;				sxattr_ptr->nodetype = temp->x.nodetype;				sxattr_ptr->xid = temp->x.xid;				sxattr_ptr->version = temp->x.version;				sxattr_ptr->offset = temp->x.offset;				sxattr_ptr->totlen = temp->x.totlen;				wpage += JFFS2_SUMMARY_XATTR_SIZE;				break;			}			case JFFS2_NODETYPE_XREF: {				struct jffs2_sum_xref_flash *sxref_ptr = wpage;				temp = c->summary->sum_list_head;				sxref_ptr->nodetype = temp->r.nodetype;				sxref_ptr->offset = temp->r.offset;				wpage += JFFS2_SUMMARY_XREF_SIZE;				break;			}#endif			default : {				if ((je16_to_cpu(temp->u.nodetype) & JFFS2_COMPAT_MASK)				    == JFFS2_FEATURE_RWCOMPAT_COPY) {					dbg_summary("Writing unknown RWCOMPAT_COPY node type %x\n",						    je16_to_cpu(temp->u.nodetype));					jffs2_sum_disable_collecting(c->summary);				} else {					BUG();	/* unknown node in summary information */				}			}		}		c->summary->sum_list_head = temp->u.next;		kfree(temp);		c->summary->sum_num--;	}	jffs2_sum_reset_collected(c->summary);	wpage += padsize;	sm = wpage;	sm->offset = cpu_to_je32(c->sector_size - jeb->free_size);	sm->magic = cpu_to_je32(JFFS2_SUM_MAGIC);	isum.sum_crc = cpu_to_je32(crc32(0, c->summary->sum_buf, datasize));	isum.node_crc = cpu_to_je32(crc32(0, &isum, sizeof(isum) - 8));	vecs[0].iov_base = &isum;	vecs[0].iov_len = sizeof(isum);	vecs[1].iov_base = c->summary->sum_buf;	vecs[1].iov_len = datasize;	sum_ofs = jeb->offset + c->sector_size - jeb->free_size;	dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n",		    sum_ofs);	ret = jffs2_flash_writev(c, vecs, 2, sum_ofs, &retlen, 0);	if (ret || (retlen != infosize)) {		JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",			      infosize, sum_ofs, ret, retlen);		if (retlen) {			/* Waste remaining space */			spin_lock(&c->erase_completion_lock);			jffs2_link_node_ref(c, jeb, sum_ofs | REF_OBSOLETE, infosize, NULL);			spin_unlock(&c->erase_completion_lock);		}		c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;		return 0;	}	spin_lock(&c->erase_completion_lock);	jffs2_link_node_ref(c, jeb, sum_ofs | REF_NORMAL, infosize, NULL);	spin_unlock(&c->erase_completion_lock);	return 0;}/* Write out summary information - called from jffs2_do_reserve_space */int jffs2_sum_write_sumnode(struct jffs2_sb_info *c){	int datasize, infosize, padsize;	struct jffs2_eraseblock *jeb;	int ret;	dbg_summary("called\n");	spin_unlock(&c->erase_completion_lock);	jeb = c->nextblock;	jffs2_prealloc_raw_node_refs(c, jeb, 1);	if (!c->summary->sum_num || !c->summary->sum_list_head) {		JFFS2_WARNING("Empty summary info!!!\n");		BUG();	}	datasize = c->summary->sum_size + sizeof(struct jffs2_sum_marker);	infosize = sizeof(struct jffs2_raw_summary) + datasize;	padsize = jeb->free_size - infosize;	infosize += padsize;	datasize += padsize;	/* Is there enough space for summary? */	if (padsize < 0) {		/* don't try to write out summary for this jeb */		jffs2_sum_disable_collecting(c->summary);		JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize);		spin_lock(&c->erase_completion_lock);		return 0;	}	ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);	spin_lock(&c->erase_completion_lock);	return ret;}

⌨️ 快捷键说明

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