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

📄 fs-ecos.c

📁 老版本的mtd-snap
💻 C
📖 第 1 页 / 共 4 页
字号:
}// -------------------------------------------------------------------------// jffs2_chdir()// Change directory support.static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,		       cyg_dir * dir_out){	D2(printf("jffs2_chdir\n"));	if (dir_out != NULL) {		// This is a request to get a new directory pointer in		// *dir_out.		jffs2_dirsearch ds;		int err;		init_dirsearch(&ds, (struct _inode *) dir,                                (const unsigned char *) name);		err = jffs2_find(&ds);		jffs2_iput(ds.dir);		if (err != ENOERR)			return err;		// check it is a directory		if (!S_ISDIR(ds.node->i_mode)) {                        jffs2_iput(ds.node);			return ENOTDIR;                }                		// Pass it out		*dir_out = (cyg_dir) ds.node;	} else {		// If no output dir is required, this means that the mte and		// dir arguments are the current cdir setting and we should		// forget this fact.		struct _inode *node = (struct _inode *) dir;		// Just decrement directory reference count.		jffs2_iput(node);	}	return ENOERR;}// -------------------------------------------------------------------------// jffs2_stat()// Get struct stat info for named object.static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name,		      struct stat *buf){	jffs2_dirsearch ds;	int err;	D2(printf("jffs2_stat\n"));	init_dirsearch(&ds, (struct _inode *) dir,                        (const unsigned char *) name);	err = jffs2_find(&ds);	jffs2_iput(ds.dir);	if (err != ENOERR)		return err;	// Fill in the status	buf->st_mode = ds.node->i_mode;	buf->st_ino = ds.node->i_ino;	buf->st_dev = 0;	buf->st_nlink = ds.node->i_nlink;	buf->st_uid = ds.node->i_uid;	buf->st_gid = ds.node->i_gid;	buf->st_size = ds.node->i_size;	buf->st_atime = ds.node->i_atime;	buf->st_mtime = ds.node->i_mtime;	buf->st_ctime = ds.node->i_ctime;	jffs2_iput(ds.node);	return ENOERR;}// -------------------------------------------------------------------------// jffs2_getinfo()// Getinfo. Currently only support pathconf().static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,			 int key, void *buf, int len){	jffs2_dirsearch ds;	int err;	D2(printf("jffs2_getinfo\n"));	init_dirsearch(&ds, (struct _inode *) dir,                        (const unsigned char *) name);	err = jffs2_find(&ds);	jffs2_iput(ds.dir);	if (err != ENOERR)		return err;	switch (key) {	case FS_INFO_CONF:		err = jffs2_pathconf(ds.node, (struct cyg_pathconf_info *) buf);		break;	default:		err = EINVAL;	}	jffs2_iput(ds.node);	return err;}// -------------------------------------------------------------------------// jffs2_setinfo()// Setinfo. Nothing to support here at present.static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,			 int key, void *buf, int len){	// No setinfo keys supported at present	D2(printf("jffs2_setinfo\n"));	return EINVAL;}//==========================================================================// File operations// -------------------------------------------------------------------------// jffs2_fo_read()// Read data from the file.static int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){	struct _inode *inode = (struct _inode *) fp->f_data;	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);	int i;	ssize_t resid = uio->uio_resid;	off_t pos = fp->f_offset;	down(&f->sem);	// Loop over the io vectors until there are none left	for (i = 0; i < uio->uio_iovcnt && pos < inode->i_size; i++) {		int ret;		cyg_iovec *iov = &uio->uio_iov[i];		off_t len = min(iov->iov_len, inode->i_size - pos);		D2(printf("jffs2_fo_read inode size %d\n", inode->i_size));		ret =		    jffs2_read_inode_range(c, f,					   (unsigned char *) iov->iov_base, pos,					   len);		if (ret) {			D1(printf			   ("jffs2_fo_read(): read_inode_range failed %d\n",			    ret));			uio->uio_resid = resid;			up(&f->sem);			return -ret;		}		resid -= len;		pos += len;	}	// We successfully read some data, update the node's access time	// and update the file offset and transfer residue.	inode->i_atime = cyg_timestamp();	uio->uio_resid = resid;	fp->f_offset = pos;	up(&f->sem);	return ENOERR;}#ifdef CYGOPT_FS_JFFS2_WRITE// -------------------------------------------------------------------------// jffs2_fo_write()// Write data to file.static int jffs2_extend_file (struct _inode *inode, struct jffs2_raw_inode *ri,		       unsigned long offset){	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);	struct jffs2_full_dnode *fn;	uint32_t phys_ofs, alloc_len;	int ret = 0;	/* Make new hole frag from old EOF to new page */	D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",		  (unsigned int)inode->i_size, offset));	ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);	if (ret)		return ret;	down(&f->sem);	ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);	ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);	ri->totlen = cpu_to_je32(sizeof(*ri));	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));	ri->version = cpu_to_je32(++f->highest_version);	ri->isize = cpu_to_je32(max((uint32_t)inode->i_size, offset));	ri->offset = cpu_to_je32(inode->i_size);	ri->dsize = cpu_to_je32(offset - inode->i_size);	ri->csize = cpu_to_je32(0);	ri->compr = JFFS2_COMPR_ZERO;	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));	ri->data_crc = cpu_to_je32(0);			fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);	jffs2_complete_reservation(c);	if (IS_ERR(fn)) {		ret = PTR_ERR(fn);		up(&f->sem);		return ret;	}	ret = jffs2_add_full_dnode_to_inode(c, f, fn);	if (f->metadata) {		jffs2_mark_node_obsolete(c, f->metadata->raw);		jffs2_free_full_dnode(f->metadata);		f->metadata = NULL;	}	if (ret) {		D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));		jffs2_mark_node_obsolete(c, fn->raw);		jffs2_free_full_dnode(fn);		up(&f->sem);		return ret;	}	inode->i_size = offset;	up(&f->sem);	return 0;}// jffs2_fo_open()// Truncate a filestatic int jffs2_truncate_file (struct _inode *inode){     struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);     struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);     struct jffs2_full_dnode *new_metadata, * old_metadata;     struct jffs2_raw_inode *ri;     uint32_t phys_ofs, alloclen;     int err;          ri = jffs2_alloc_raw_inode();     if (!ri) {          return ENOMEM;     }     err = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);          if (err) {          jffs2_free_raw_inode(ri);          return err;     }     down(&f->sem);     ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);     ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);     ri->totlen = cpu_to_je32(sizeof(*ri));     ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));          ri->ino = cpu_to_je32(inode->i_ino);     ri->version = cpu_to_je32(++f->highest_version);          ri->uid = cpu_to_je16(inode->i_uid);     ri->gid = cpu_to_je16(inode->i_gid);     ri->mode = cpu_to_jemode(inode->i_mode);     ri->isize = cpu_to_je32(0);     ri->atime = cpu_to_je32(inode->i_atime);     ri->mtime = cpu_to_je32(cyg_timestamp());     ri->offset = cpu_to_je32(0);     ri->csize = ri->dsize = cpu_to_je32(0);     ri->compr = JFFS2_COMPR_NONE;     ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));     ri->data_crc = cpu_to_je32(0);     new_metadata = jffs2_write_dnode(c, f, ri, NULL, 0,                                       phys_ofs, ALLOC_NORMAL);     if (IS_ERR(new_metadata)) {          jffs2_complete_reservation(c);          jffs2_free_raw_inode(ri);          up(&f->sem);          return PTR_ERR(new_metadata);     }          /* It worked. Update the inode */     inode->i_mtime = cyg_timestamp();     inode->i_size = 0;     old_metadata = f->metadata;     jffs2_truncate_fragtree (c, &f->fragtree, 0);     f->metadata = new_metadata;     if (old_metadata) {          jffs2_mark_node_obsolete(c, old_metadata->raw);          jffs2_free_full_dnode(old_metadata);     }     jffs2_free_raw_inode(ri);          up(&f->sem);     jffs2_complete_reservation(c);          return 0;}static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){	struct _inode *inode = (struct _inode *) fp->f_data;	off_t pos = fp->f_offset;	ssize_t resid = uio->uio_resid;	struct jffs2_raw_inode ri;	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);	int i;	// If the APPEND mode bit was supplied, force all writes to	// the end of the file.	if (fp->f_flag & CYG_FAPPEND)		pos = fp->f_offset = inode->i_size;	if (pos < 0)		return EINVAL;	memset(&ri, 0, sizeof(ri));	ri.ino = cpu_to_je32(f->inocache->ino);	ri.mode = cpu_to_jemode(inode->i_mode);	ri.uid = cpu_to_je16(inode->i_uid);	ri.gid = cpu_to_je16(inode->i_gid);	ri.atime = ri.ctime = ri.mtime = cpu_to_je32(cyg_timestamp());	if (pos > inode->i_size) {		int err;		ri.version = cpu_to_je32(++f->highest_version);		err = jffs2_extend_file(inode, &ri, pos);		if (err)			return -err;	}	ri.isize = cpu_to_je32(inode->i_size);	// Now loop over the iovecs until they are all done, or	// we get an error.	for (i = 0; i < uio->uio_iovcnt; i++) {		cyg_iovec *iov = &uio->uio_iov[i];		unsigned char *buf = iov->iov_base;		off_t len = iov->iov_len;		uint32_t writtenlen;		int err;		D2(printf("jffs2_fo_write page_start_pos %d\n", pos));		D2(printf("jffs2_fo_write transfer size %d\n", len));		err = jffs2_write_inode_range(c, f, &ri, buf,					      pos, len, &writtenlen);		if (err)			return -err;				if (writtenlen != len)			return ENOSPC;		pos += len;		resid -= len;	}	// We wrote some data successfully, update the modified and access	// times of the inode, increase its size appropriately, and update	// the file offset and transfer residue.	inode->i_mtime = inode->i_ctime = je32_to_cpu(ri.mtime);	if (pos > inode->i_size)		inode->i_size = pos;	uio->uio_resid = resid;	fp->f_offset = pos;	return ENOERR;}#endif /* CYGOPT_FS_JFFS2_WRITE */// -------------------------------------------------------------------------// jffs2_fo_lseek()// Seek to a new file position.static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * apos, int whence){	struct _inode *node = (struct _inode *) fp->f_data;	off_t pos = *apos;	D2(printf("jffs2_fo_lseek\n"));	switch (whence) {	case SEEK_SET:		// Pos is already where we want to be.		break;	case SEEK_CUR:		// Add pos to current offset.		pos += fp->f_offset;		break;	case SEEK_END:		// Add pos to file size.		pos += node->i_size;		break;	default:		return EINVAL;	}        if (pos < 0 )                return EINVAL;	// All OK, set fp offset and return new position.	*apos = fp->f_offset = pos;	return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_ioctl()// Handle ioctls. Currently none are defined.static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,			  CYG_ADDRWORD data){	// No Ioctls currenly defined.	D2(printf("jffs2_fo_ioctl\n"));	return EINVAL;}// -------------------------------------------------------------------------// jffs2_fo_fsync().// Force the file out to data storage.static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode){	// Data is always permanently where it belongs, nothing to do	// here.	D2(printf("jffs2_fo_fsync\n"));	return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_close()// Close a file. We just decrement the refcnt and let it go away if// that is all that is keeping it here.static int jffs2_fo_close(struct CYG_FILE_TAG *fp){	struct _inode *node = (struct _inode *) fp->f_data;	D2(printf("jffs2_fo_close\n"));	jffs2_iput(node);	fp->f_data = 0;		// zero data pointer	return ENOERR;}// -------------------------------------------------------------------------//jffs2_fo_fstat()// Get file status.static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf){	struct _inode *node = (struct _inode *) fp->f_data;	D2(printf("jffs2_fo_fstat\n"));	// Fill in the status	buf->st_mode = node->i_mode;	buf->st_ino = node->i_ino;	buf->st_dev = 0;	buf->st_nlink = node->i_nlink;	buf->st_uid = node->i_uid;	buf->st_gid = node->i_gid;	buf->st_size = node->i_size;	buf->st_atime = node->i_atime;	buf->st_mtime = node->i_mtime;	buf->st_ctime = node->i_ctime;	return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_getinfo()// Get info. Currently only supports fpathconf().static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf,			    int len){	struct _inode *node = (struct _inode *) fp->f_data;	int err;	D2(printf("jffs2_fo_getinfo\n"));	switch (key) {	case FS_INFO_CONF:		err = jffs2_pathconf(node, (struct cyg_pathconf_info *) buf);		break;	default:		err = EINVAL;	}	return err;	return ENOERR;}// -------------------------------------------------------------------------// jffs2_fo_setinfo()// Set info. Nothing supported here.static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf,			    int len){	// No setinfo key supported at present

⌨️ 快捷键说明

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