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

📄 fs-ecos.c

📁 mtd-snapshot-20041027
💻 C
📖 第 1 页 / 共 4 页
字号:
	memcpy(nbuf, name, len);	nbuf[len] = '\0';}static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){	struct _inode *d_inode = (struct _inode *) fp->f_data;	struct dirent *ent = (struct dirent *) uio->uio_iov[0].iov_base;	char *nbuf = ent->d_name;	int nlen = sizeof (ent->d_name) - 1;	off_t len = uio->uio_iov[0].iov_len;	struct jffs2_inode_info *f;	struct jffs2_sb_info *c;	struct _inode *inode = d_inode;	struct jffs2_full_dirent *fd;	unsigned long offset, curofs;	int found = 1;	if (len < sizeof (struct dirent))		return EINVAL;	D1(printk	   (KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", d_inode->i_ino));	f = JFFS2_INODE_INFO(inode);	c = JFFS2_SB_INFO(inode->i_sb);	offset = fp->f_offset;	if (offset == 0) {		D1(printk		   (KERN_DEBUG "Dirent 0: \".\", ino #%lu\n", inode->i_ino));		filldir(nbuf, nlen, ".", 1);		goto out;	}	if (offset == 1) {		filldir(nbuf, nlen, "..", 2);		goto out;	}	curofs = 1;	down(&f->sem);	for (fd = f->dents; fd; fd = fd->next) {		curofs++;		/* First loop: curofs = 2; offset = 2 */		if (curofs < offset) {			D2(printk			   (KERN_DEBUG			    "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",			    fd->name, fd->ino, fd->type, curofs, offset));			continue;		}		if (!fd->ino) {			D2(printk			   (KERN_DEBUG "Skipping deletion dirent \"%s\"\n",			    fd->name));			offset++;			continue;		}		D2(printk		   (KERN_DEBUG "Dirent %ld: \"%s\", ino #%u, type %d\n", offset,		    fd->name, fd->ino, fd->type));		filldir(nbuf, nlen, fd->name, strlen(fd->name));		goto out_sem;	}	/* Reached the end of the directory */	found = 0;      out_sem:	up(&f->sem);      out:	fp->f_offset = ++offset;	if (found) {		uio->uio_resid -= sizeof (struct dirent);	}	return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_dirlseek()// Seek directory to start.static int jffs2_fo_dirlseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence){	// Only allow SEEK_SET to zero	D2(printf("jffs2_fo_dirlseek\n"));	if (whence != SEEK_SET || *pos != 0)		return EINVAL;	*pos = fp->f_offset = 0;	return ENOERR;}//==========================================================================// // Called by JFFS2// ===============// ////==========================================================================unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, 				   struct jffs2_inode_info *f, 				   unsigned long offset,				   unsigned long *priv){	/* FIXME: This works only with one file system mounted at a time */	int ret;	ret = jffs2_read_inode_range(c, f, gc_buffer, offset, PAGE_CACHE_SIZE);	if (ret)		return ERR_PTR(ret);	return gc_buffer;}void jffs2_gc_release_page(struct jffs2_sb_info *c,			   unsigned char *ptr,			   unsigned long *priv){	/* Do nothing */}static struct _inode *new_inode(struct super_block *sb){	// Only called in write.c jffs2_new_inode	// Always adds itself to inode cache	struct _inode *inode;	struct _inode *cached_inode;	inode = malloc(sizeof (struct _inode));	if (inode == NULL)		return 0;	D2(printf	   ("malloc new_inode %x ####################################\n",	    inode));	memset(inode, 0, sizeof (struct _inode));	inode->i_sb = sb;	inode->i_ino = 1;	inode->i_count = 1;	inode->i_nlink = 1;	// Let JFFS2 manage the link count	inode->i_size = 0;	inode->i_cache_next = NULL;	// Newest inode, about to be cached	// Add to the icache	for (cached_inode = sb->s_root; cached_inode != NULL;	     cached_inode = cached_inode->i_cache_next) {		if (cached_inode->i_cache_next == NULL) {			cached_inode->i_cache_next = inode;	// Current last in cache points to newcomer			inode->i_cache_prev = cached_inode;	// Newcomer points back to last			break;		}	}	return inode;}static struct _inode *ilookup(struct super_block *sb, cyg_uint32 ino){	struct _inode *inode = NULL;	D2(printf("ilookup\n"));	// Check for this inode in the cache	for (inode = sb->s_root; inode != NULL; inode = inode->i_cache_next) {		if (inode->i_ino == ino) {			inode->i_count++;			break;		}	}	return inode;}struct _inode *jffs2_iget(struct super_block *sb, cyg_uint32 ino){	// Called in super.c jffs2_read_super, dir.c jffs2_lookup,	// and gc.c jffs2_garbage_collect_pass	// Must first check for cached inode 	// If this fails let new_inode create one	struct _inode *inode;	int err;	D2(printf("jffs2_iget\n"));	inode = ilookup(sb, ino);	if (inode)		return inode;	// Not cached, so malloc it	inode = new_inode(sb);	if (inode == NULL)		return 0;	inode->i_ino = ino;	err = jffs2_read_inode(inode);	if (err) {		printf("jffs2_read_inode() failed\n");		jffs2_iput(inode);		inode = NULL;		return ERR_PTR(err);	}	return inode;}// -------------------------------------------------------------------------// Decrement the reference count on an inode. If this makes the ref count// zero, then this inode can be freed.void jffs2_iput(struct _inode *i){	// Called in jffs2_find 	// (and jffs2_open and jffs2_ops_mkdir?)	// super.c jffs2_read_super,	// and gc.c jffs2_garbage_collect_pass recurse:	if (!i) {		printf("jffs2_iput() called with NULL inode\n");		// and let it fault... 	}	i->i_count--;	if (i->i_count < 0)		BUG();	if (i->i_count)		return;	if (!i->i_nlink) {		struct _inode *parent;		// Remove from the icache linked list and free immediately		if (i->i_cache_prev)			i->i_cache_prev->i_cache_next = i->i_cache_next;		if (i->i_cache_next)			i->i_cache_next->i_cache_prev = i->i_cache_prev;		parent = i->i_parent;		jffs2_clear_inode(i);		memset(i, 0x5a, sizeof(*i));		free(i);		if (parent && parent != i) {			i = parent;			goto recurse;		}	} else {		// Evict some _other_ inode with i_count zero, leaving		// this latest one in the cache for a while 		icache_evict(i->i_sb->s_root, i);	}}// -------------------------------------------------------------------------// EOF jffs2.cstatic inline void jffs2_init_inode_info(struct jffs2_inode_info *f){	memset(f, 0, sizeof(*f));	init_MUTEX_LOCKED(&f->sem);}static 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_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));        jffs2_do_clear_inode(c, f);}/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,   fill in the raw_inode while you're at it. */struct _inode *jffs2_new_inode (struct _inode *dir_i, int mode, struct jffs2_raw_inode *ri){	struct _inode *inode;	struct super_block *sb = dir_i->i_sb;	struct jffs2_sb_info *c;	struct jffs2_inode_info *f;	int ret;	D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));	c = JFFS2_SB_INFO(sb);		inode = new_inode(sb);		if (!inode)		return ERR_PTR(-ENOMEM);	f = JFFS2_INODE_INFO(inode);	jffs2_init_inode_info(f);	memset(ri, 0, sizeof(*ri));	/* Set OS-specific defaults for new inodes */	ri->uid = ri->gid = cpu_to_je16(0);	ri->mode =  cpu_to_jemode(mode);	ret = jffs2_do_new_inode (c, f, mode, ri);	if (ret) {		jffs2_iput(inode);		return ERR_PTR(ret);	}	inode->i_nlink = 1;	inode->i_ino = je32_to_cpu(ri->ino);	inode->i_mode = jemode_to_cpu(ri->mode);	inode->i_gid = je16_to_cpu(ri->gid);	inode->i_uid = je16_to_cpu(ri->uid);	inode->i_atime = inode->i_ctime = inode->i_mtime = cyg_timestamp();	ri->atime = ri->mtime = ri->ctime = cpu_to_je32(inode->i_mtime);	inode->i_size = 0;	return inode;}static int jffs2_read_inode (struct _inode *inode){	struct jffs2_inode_info *f;	struct jffs2_sb_info *c;	struct jffs2_raw_inode latest_node;	int ret;	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);	jffs2_init_inode_info(f);		ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);	if (ret) {		up(&f->sem);		return ret;	}	inode->i_mode = jemode_to_cpu(latest_node.mode);	inode->i_uid = je16_to_cpu(latest_node.uid);	inode->i_gid = je16_to_cpu(latest_node.gid);	inode->i_size = je32_to_cpu(latest_node.isize);	inode->i_atime = je32_to_cpu(latest_node.atime);	inode->i_mtime = je32_to_cpu(latest_node.mtime);	inode->i_ctime = je32_to_cpu(latest_node.ctime);	inode->i_nlink = f->inocache->nlink;	up(&f->sem);	D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));	return 0;}void jffs2_gc_release_inode(struct jffs2_sb_info *c,				   struct jffs2_inode_info *f){	jffs2_iput(OFNI_EDONI_2SFFJ(f));}struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,						     int inum, int nlink){	struct _inode *inode;	struct jffs2_inode_cache *ic;	if (!nlink) {		/* The inode has zero nlink but its nodes weren't yet marked		   obsolete. This has to be because we're still waiting for 		   the final (close() and) jffs2_iput() to happen.		   There's a possibility that the final jffs2_iput() could have 		   happened while we were contemplating. In order to ensure		   that we don't cause a new read_inode() (which would fail)		   for the inode in question, we use ilookup() in this case		   instead of jffs2_iget().		   The nlink can't _become_ zero at this point because we're 		   holding the alloc_sem, and jffs2_do_unlink() would also		   need that while decrementing nlink on any inode.		*/		inode = ilookup(OFNI_BS_2SFFJ(c), inum);		if (!inode) {			D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",				  inum));			spin_lock(&c->inocache_lock);			ic = jffs2_get_ino_cache(c, inum);			if (!ic) {				D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));				spin_unlock(&c->inocache_lock);				return NULL;			}			if (ic->state != INO_STATE_CHECKEDABSENT) {				/* Wait for progress. Don't just loop */				D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",					  ic->ino, ic->state));				sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);			} else {				spin_unlock(&c->inocache_lock);			}			return NULL;		}	} else {		/* Inode has links to it still; they're not going away because		   jffs2_do_unlink() would need the alloc_sem and we have it.		   Just jffs2_iget() it, and if read_inode() is necessary that's OK.		*/		inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum);		if (IS_ERR(inode))			return (void *)inode;	}	return JFFS2_INODE_INFO(inode);}uint32_t jffs2_from_os_mode(uint32_t osmode){	uint32_t jmode = ((osmode & S_IRUSR)?00400:0) |		((osmode & S_IWUSR)?00200:0) |		((osmode & S_IXUSR)?00100:0) |		((osmode & S_IRGRP)?00040:0) |		((osmode & S_IWGRP)?00020:0) |		((osmode & S_IXGRP)?00010:0) |		((osmode & S_IROTH)?00004:0) |		((osmode & S_IWOTH)?00002:0) |		((osmode & S_IXOTH)?00001:0);	switch (osmode & S_IFMT) {	case S_IFSOCK:		return jmode | 0140000;	case S_IFLNK:		return jmode | 0120000;	case S_IFREG:		return jmode | 0100000;	case S_IFBLK:		return jmode | 0060000;	case S_IFDIR:		return jmode | 0040000;	case S_IFCHR:		return jmode | 0020000;	case S_IFIFO:		return jmode | 0010000;	case S_ISUID:		return jmode | 0004000;	case S_ISGID:		return jmode | 0002000;#ifdef S_ISVTX	case S_ISVTX:		return jmode | 0001000;#endif	}	printf("os_to_jffs2_mode() cannot convert 0x%x\n", osmode);	BUG();	return 0;}uint32_t jffs2_to_os_mode (uint32_t jmode){	uint32_t osmode = ((jmode & 00400)?S_IRUSR:0) |		((jmode & 00200)?S_IWUSR:0) |		((jmode & 00100)?S_IXUSR:0) |		((jmode & 00040)?S_IRGRP:0) |		((jmode & 00020)?S_IWGRP:0) |		((jmode & 00010)?S_IXGRP:0) |		((jmode & 00004)?S_IROTH:0) |		((jmode & 00002)?S_IWOTH:0) |		((jmode & 00001)?S_IXOTH:0);	switch(jmode & 00170000) {	case 0140000:		return osmode | S_IFSOCK;	case 0120000:		return osmode | S_IFLNK;	case 0100000:		return osmode | S_IFREG;	case 0060000:		return osmode | S_IFBLK;	case 0040000:		return osmode | S_IFDIR;	case 0020000:		return osmode | S_IFCHR;	case 0010000:		return osmode | S_IFIFO;	case 0004000:		return osmode | S_ISUID;	case 0002000:		return osmode | S_ISGID;#ifdef S_ISVTX	case 0001000:		return osmode | S_ISVTX;#endif	}	printf("jffs2_to_os_mode() cannot convert 0x%x\n", osmode);	BUG();	return 0;}

⌨️ 快捷键说明

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