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

📄 scan.c

📁 uclinux的jffs2文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
		curofs += retlen&~3;	}	D1(printk(KERN_DEBUG "Empty flash detected from 0x%08x to 0x%08x\n", *startofs, curofs));	kfree(buf);	*startofs = curofs;	return 0;}static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, __u32 ino){	struct jffs2_inode_cache *ic;	ic = jffs2_get_ino_cache(c, ino);	if (ic)		return ic;	ic = jffs2_alloc_inode_cache();	if (!ic) {		printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n");		return NULL;	}	memset(ic, 0, sizeof(*ic));	ic->scan = kmalloc(sizeof(struct jffs2_scan_info), GFP_KERNEL);	if (!ic->scan) {		printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of scan info for inode cache failed\n");		jffs2_free_inode_cache(ic);		return NULL;	}	memset(ic->scan, 0, sizeof(*ic->scan));	ic->ino = ino;	ic->nodes = (void *)ic;	jffs2_add_ino_cache(c, ic);	if (ino == 1)		ic->nlink=1;	return ic;}static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs){	struct jffs2_raw_node_ref *raw;	struct jffs2_full_dnode *fn;	struct jffs2_tmp_dnode_info *tn, **tn_list;	struct jffs2_inode_cache *ic;	struct jffs2_raw_inode ri;	__u32 crc;	__u16 oldnodetype;	int ret;	ssize_t retlen;	D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", *ofs));	ret = c->mtd->read(c->mtd, *ofs, sizeof(ri), &retlen, (char *)&ri);	if (ret) {		printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs, ret);		return ret;	}	if (retlen != sizeof(ri)) {		printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 		       retlen, *ofs, sizeof(ri));		return -EIO;	}	/* We sort of assume that the node was accurate when it was 	   first written to the medium :) */	oldnodetype = ri.nodetype;	ri.nodetype |= JFFS2_NODE_ACCURATE;	crc = crc32(0, &ri, sizeof(ri)-8);	ri.nodetype = oldnodetype;	if(crc != ri.node_crc) {		printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",		       *ofs, ri.node_crc, crc);		/* FIXME: Why do we believe totlen? */		DIRTY_SPACE(4);		*ofs += 4;		return 0;	}	/* There was a bug where we wrote hole nodes out with csize/dsize	   swapped. Deal with it */	if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) {		ri.dsize = ri.csize;		ri.csize = 0;	}	if (ri.csize) {		/* Check data CRC too */		unsigned char *dbuf;		__u32 crc;		dbuf = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);		if (!dbuf) {			printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of temporary data buffer for CRC check failed\n");			return -ENOMEM;		}		ret = c->mtd->read(c->mtd, *ofs+sizeof(ri), ri.csize, &retlen, dbuf);		if (ret) {			printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs+sizeof(ri), ret);			kfree(dbuf);			return ret;		}		if (retlen != ri.csize) {			printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 			       retlen, *ofs+ sizeof(ri), ri.csize);			kfree(dbuf);			return -EIO;		}		crc = crc32(0, dbuf, ri.csize);		kfree(dbuf);		if (crc != ri.data_crc) {			printk(KERN_NOTICE "jffs2_scan_inode_node(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",			       *ofs, ri.data_crc, crc);			DIRTY_SPACE(PAD(ri.totlen));			*ofs += PAD(ri.totlen);			return 0;		}	}	/* Wheee. It worked */	raw = jffs2_alloc_raw_node_ref();	if (!raw) {		printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");		return -ENOMEM;	}	tn = jffs2_alloc_tmp_dnode_info();	if (!tn) {		jffs2_free_raw_node_ref(raw);		return -ENOMEM;	}	fn = jffs2_alloc_full_dnode();	if (!fn) {		jffs2_free_tmp_dnode_info(tn);		jffs2_free_raw_node_ref(raw);		return -ENOMEM;	}	ic = jffs2_scan_make_ino_cache(c, ri.ino);	if (!ic) {		jffs2_free_full_dnode(fn);		jffs2_free_tmp_dnode_info(tn);		jffs2_free_raw_node_ref(raw);		return -ENOMEM;	}	/* Build the data structures and file them for later */	raw->flash_offset = *ofs;	raw->totlen = PAD(ri.totlen);	raw->next_phys = NULL;	raw->next_in_ino = ic->nodes;	ic->nodes = raw;	if (!jeb->first_node)		jeb->first_node = raw;	if (jeb->last_node)		jeb->last_node->next_phys = raw;	jeb->last_node = raw;	D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", 		  ri.ino, ri.version, ri.offset, ri.offset+ri.dsize));	pseudo_random += ri.version;	for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) {		if ((*tn_list)->version < ri.version)			continue;		if ((*tn_list)->version > ri.version) 			break;		/* Wheee. We've found another instance of the same version number.		   We should obsolete one of them. 		*/		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));		if (!jeb->used_size) {			D1(printk(KERN_DEBUG "No valid nodes yet found in this eraseblock 0x%08x, so obsoleting the new instance at 0x%08x\n", 				  jeb->offset, raw->flash_offset & ~3));			ri.nodetype &= ~JFFS2_NODE_ACCURATE;			/* Perhaps we could also mark it as such on the medium. Maybe later */		}		break;	}	if (ri.nodetype & JFFS2_NODE_ACCURATE) {		memset(fn,0,sizeof(*fn));		fn->ofs = ri.offset;		fn->size = ri.dsize;		fn->frags = 0;		fn->raw = raw;		tn->next = NULL;		tn->fn = fn;		tn->version = ri.version;		USED_SPACE(PAD(ri.totlen));		jffs2_add_tn_to_list(tn, &ic->scan->tmpnodes);		/* Make sure the one we just added is the _last_ in the list		   with this version number, so the older ones get obsoleted */		while (tn->next && tn->next->version == tn->version) {			D1(printk(KERN_DEBUG "Shifting new node at 0x%08x after other node at 0x%08x for version %d in list\n",				  fn->raw->flash_offset&~3, tn->next->fn->raw->flash_offset &~3, ri.version));			if(tn->fn != fn)				BUG();			tn->fn = tn->next->fn;			tn->next->fn = fn;			tn = tn->next;		}	} else {		jffs2_free_full_dnode(fn);		jffs2_free_tmp_dnode_info(tn);		raw->flash_offset |= 1;		DIRTY_SPACE(PAD(ri.totlen));	}			*ofs += PAD(ri.totlen);	return 0;}static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs){	struct jffs2_raw_node_ref *raw;	struct jffs2_full_dirent *fd;	struct jffs2_inode_cache *ic;	struct jffs2_raw_dirent rd;	__u16 oldnodetype;	int ret;	__u32 crc;	ssize_t retlen;	D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", *ofs));	ret = c->mtd->read(c->mtd, *ofs, sizeof(rd), &retlen, (char *)&rd);	if (ret) {		printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", *ofs, ret);		return ret;	}	if (retlen != sizeof(rd)) {		printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 		       retlen, *ofs, sizeof(rd));		return -EIO;	}	/* We sort of assume that the node was accurate when it was 	   first written to the medium :) */	oldnodetype = rd.nodetype;	rd.nodetype |= JFFS2_NODE_ACCURATE;	crc = crc32(0, &rd, sizeof(rd)-8);	rd.nodetype = oldnodetype;	if (crc != rd.node_crc) {		printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",		       *ofs, rd.node_crc, crc);		/* FIXME: Why do we believe totlen? */		DIRTY_SPACE(4);		*ofs += 4;		return 0;	}	pseudo_random += rd.version;	fd = jffs2_alloc_full_dirent(rd.nsize+1);	if (!fd) {		return -ENOMEM;}	ret = c->mtd->read(c->mtd, *ofs + sizeof(rd), rd.nsize, &retlen, &fd->name[0]);	if (ret) {		jffs2_free_full_dirent(fd);		printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", 		       *ofs + sizeof(rd), ret);		return ret;	}	if (retlen != rd.nsize) {		jffs2_free_full_dirent(fd);		printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", 		       retlen, *ofs + sizeof(rd), rd.nsize);		return -EIO;	}	crc = crc32(0, fd->name, rd.nsize);	if (crc != rd.name_crc) {		printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",		       *ofs, rd.name_crc, crc);			fd->name[rd.nsize]=0;		D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));		jffs2_free_full_dirent(fd);		/* FIXME: Why do we believe totlen? */		DIRTY_SPACE(PAD(rd.totlen));		*ofs += PAD(rd.totlen);		return 0;	}	raw = jffs2_alloc_raw_node_ref();	if (!raw) {		jffs2_free_full_dirent(fd);		printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");		return -ENOMEM;	}	ic = jffs2_scan_make_ino_cache(c, rd.pino);	if (!ic) {		jffs2_free_full_dirent(fd);		jffs2_free_raw_node_ref(raw);		return -ENOMEM;	}		raw->totlen = PAD(rd.totlen);	raw->flash_offset = *ofs;	raw->next_phys = NULL;	raw->next_in_ino = ic->nodes;	ic->nodes = raw;	if (!jeb->first_node)		jeb->first_node = raw;	if (jeb->last_node)		jeb->last_node->next_phys = raw;	jeb->last_node = raw;	if (rd.nodetype & JFFS2_NODE_ACCURATE) {		fd->raw = raw;		fd->next = NULL;		fd->version = rd.version;		fd->ino = rd.ino;		fd->name[rd.nsize]=0;		fd->nhash = full_name_hash(fd->name, rd.nsize);		fd->type = rd.type;		USED_SPACE(PAD(rd.totlen));		jffs2_add_fd_to_list(c, fd, &ic->scan->dents);	} else {		raw->flash_offset |= 1;		jffs2_free_full_dirent(fd);		DIRTY_SPACE(PAD(rd.totlen));	} 	*ofs += PAD(rd.totlen);	return 0;}static int count_list(struct list_head *l){	uint32_t count = 0;	struct list_head *tmp;	list_for_each(tmp, l) {		count++;	}	return count;}/* Note: This breaks if list_empty(head). I don't care. You   might, if you copy this code and use it elsewhere :) */static void rotate_list(struct list_head *head, uint32_t count){	struct list_head *n = head->next;	list_del(head);	while(count--)		n = n->next;	list_add(head, n);}static void jffs2_rotate_lists(struct jffs2_sb_info *c){	uint32_t x;	x = count_list(&c->clean_list);	if (x)		rotate_list((&c->clean_list), pseudo_random % x);	x = count_list(&c->dirty_list);	if (x)		rotate_list((&c->dirty_list), pseudo_random % x);	if (c->nr_erasing_blocks)		rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks);	if (c->nr_free_blocks) /* Not that it should ever be zero */		rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks);}

⌨️ 快捷键说明

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