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

📄 readinode.c

📁 这是著名的jffs2嵌入式日志文件系统的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	__u32 mdata_ver = 0;	int ret;	ssize_t retlen;	D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));	f = JFFS2_INODE_INFO(inode);	c = JFFS2_SB_INFO(inode->i_sb);	memset(f, 0, sizeof(*f));	D2(printk(KERN_DEBUG "getting inocache\n"));	init_MUTEX(&f->sem);	f->inocache = jffs2_get_ino_cache(c, inode->i_ino);	D2(printk(KERN_DEBUG "jffs2_read_inode(): Got inocache at %p\n", f->inocache));	if (!f->inocache && inode->i_ino == 1) {		/* Special case - no root inode on medium */		f->inocache = jffs2_alloc_inode_cache();		if (!f->inocache) {			printk(KERN_CRIT "jffs2_read_inode(): Cannot allocate inocache for root inode\n");			make_bad_inode(inode);			return;		}		D1(printk(KERN_DEBUG "jffs2_read_inode(): Creating inocache for root inode\n"));		memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));		f->inocache->ino = f->inocache->nlink = 1;		f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;		jffs2_add_ino_cache(c, f->inocache);	}	if (!f->inocache) {		printk(KERN_WARNING "jffs2_read_inode() on nonexistent ino %lu\n", (unsigned long)inode->i_ino);		make_bad_inode(inode);		return;	}	D1(printk(KERN_DEBUG "jffs2_read_inode(): ino #%lu nlink is %d\n", (unsigned long)inode->i_ino, f->inocache->nlink));	inode->i_nlink = f->inocache->nlink;	/* Grab all nodes relevant to this ino */	ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);	if (ret) {		printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);		make_bad_inode(inode);		return;	}	f->dents = fd_list;	while (tn_list) {		tn = tn_list;		fn = tn->fn;		if (f->metadata && tn->version > mdata_ver) {			D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3));			jffs2_mark_node_obsolete(c, f->metadata->raw);			jffs2_free_full_dnode(f->metadata);			f->metadata = NULL;						mdata_ver = 0;		}		if (fn->size) {			jffs2_add_full_dnode_to_inode(c, f, fn);		} else {			/* Zero-sized node at end of version list. Just a metadata update */			D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", fn->raw->flash_offset &~3, tn->version));			f->metadata = fn;			mdata_ver = tn->version;		}		tn_list = tn->next;		jffs2_free_tmp_dnode_info(tn);	}	if (!fn) {		/* No data nodes for this inode. */		if (inode->i_ino != 1) {			printk(KERN_WARNING "jffs2_read_inode(): No data nodes found for ino #%lu\n", inode->i_ino);			if (!fd_list) {				make_bad_inode(inode);				return;			}			printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n");		}		inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;		latest_node.version = 0;		inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;		inode->i_nlink = f->inocache->nlink;		inode->i_size = 0;	} else {		__u32 crc;		ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(latest_node), &retlen, (void *)&latest_node);		if (ret || retlen != sizeof(latest_node)) {			printk(KERN_NOTICE "MTD read in jffs2_read_inode() failed: Returned %d, %ld of %d bytes read\n",			       ret, (long)retlen, sizeof(latest_node));			jffs2_clear_inode(inode);			make_bad_inode(inode);			return;		}		crc = crc32(0, &latest_node, sizeof(latest_node)-8);		if (crc != latest_node.node_crc) {			printk(KERN_NOTICE "CRC failed for read_inode of inode %ld at physical location 0x%x\n", inode->i_ino, fn->raw->flash_offset & ~3);			jffs2_clear_inode(inode);			make_bad_inode(inode);			return;		}		inode->i_mode = latest_node.mode;		inode->i_uid = latest_node.uid;		inode->i_gid = latest_node.gid;		inode->i_size = latest_node.isize;		if (S_ISREG(inode->i_mode))			jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize);		inode->i_atime = latest_node.atime;		inode->i_mtime = latest_node.mtime;		inode->i_ctime = latest_node.ctime;	}	/* OK, now the special cases. Certain inode types should	   have only one data node, and it's kept as the metadata	   node */	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) ||	    S_ISLNK(inode->i_mode)) {		if (f->metadata) {			printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had metadata node\n", inode->i_ino, inode->i_mode);			jffs2_clear_inode(inode);			make_bad_inode(inode);			return;		}		if (!f->fraglist) {			printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o has no fragments\n", inode->i_ino, inode->i_mode);			jffs2_clear_inode(inode);			make_bad_inode(inode);			return;		}		/* ASSERT: f->fraglist != NULL */		if (f->fraglist->next) {			printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had more than one node\n", inode->i_ino, inode->i_mode);			/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */			jffs2_clear_inode(inode);			make_bad_inode(inode);			return;		}		/* OK. We're happy */		f->metadata = f->fraglist->node;		jffs2_free_node_frag(f->fraglist);		f->fraglist = NULL;	}				    	inode->i_blksize = PAGE_SIZE;	inode->i_blocks = (inode->i_size + 511) >> 9;		switch (inode->i_mode & S_IFMT) {		unsigned short rdev;	case S_IFLNK:		inode->i_op = &jffs2_symlink_inode_operations;		/* Hack to work around broken isize in old symlink code.		   Remove this when dwmw2 comes to his senses and stops		   symlinks from being an entirely gratuitous special		   case. */		if (!inode->i_size)			inode->i_size = latest_node.dsize;		break;			case S_IFDIR:		if (mctime_ver > latest_node.version) {			/* The times in the latest_node are actually older than			   mctime in the latest dirent. Cheat. */			inode->i_mtime = inode->i_ctime = inode->i_atime = 				latest_mctime;		}		inode->i_op = &jffs2_dir_inode_operations;		inode->i_fop = &jffs2_dir_operations;		break;	case S_IFREG:		inode->i_op = &jffs2_file_inode_operations;		inode->i_fop = &jffs2_file_operations;		inode->i_mapping->a_ops = &jffs2_file_address_operations;		inode->i_mapping->nrpages = 0;		break;	case S_IFBLK:	case S_IFCHR:		/* Read the device numbers from the media */		D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));		if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {			/* Eep */			printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);			jffs2_clear_inode(inode);			make_bad_inode(inode);			return;		}				case S_IFSOCK:	case S_IFIFO:		inode->i_op = &jffs2_file_inode_operations;		init_special_inode(inode, inode->i_mode, kdev_t_to_nr(MKDEV(rdev>>8, rdev&0xff)));		break;	default:		printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu", inode->i_mode, (unsigned long)inode->i_ino);	}	D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));}void jffs2_clear_inode (struct inode *inode){	/* We can forget about this inode for now - drop all 	 *  the nodelists associated with it, etc.	 */	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);	struct jffs2_node_frag *frag, *frags;	struct jffs2_full_dirent *fd, *fds;	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);	D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));	down(&f->sem);	frags = f->fraglist;	fds = f->dents;	if (f->metadata) {		if (!f->inocache->nlink)			jffs2_mark_node_obsolete(c, f->metadata->raw);		jffs2_free_full_dnode(f->metadata);	}	while (frags) {		frag = frags;		frags = frag->next;		D2(printk(KERN_DEBUG "jffs2_clear_inode: frag at 0x%x-0x%x: node %p, frags %d--\n", frag->ofs, frag->ofs+frag->size, frag->node, frag->node?frag->node->frags:0));		if (frag->node && !(--frag->node->frags)) {			/* Not a hole, and it's the final remaining frag of this node. Free the node */			if (!f->inocache->nlink)				jffs2_mark_node_obsolete(c, frag->node->raw);			jffs2_free_full_dnode(frag->node);		}		jffs2_free_node_frag(frag);	}	while(fds) {		fd = fds;		fds = fd->next;		jffs2_free_full_dirent(fd);	}	up(&f->sem);};

⌨️ 快捷键说明

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