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

📄 fs-ecos.c

📁 老版本的mtd-snap
💻 C
📖 第 1 页 / 共 4 页
字号:
// Open a directory for reading.static int jffs3_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,			 cyg_file * file){	jffs3_dirsearch ds;	int err;	D2(printf("jffs3_opendir\n"));	init_dirsearch(&ds, (struct _inode *) dir, name);	err = jffs3_find(&ds);	jffs3_iput(ds.dir);	if (err != ENOERR)		return err;	// check it is really a directory.	if (!S_ISDIR(ds.node->i_mode)) {		jffs3_iput(ds.node);		return ENOTDIR;	}	// Initialize the file object, setting the f_ops field to a	// special set of file ops.	file->f_type = CYG_FILE_TYPE_FILE;	file->f_ops = &jffs3_dirops;	file->f_offset = 0;	file->f_data = (CYG_ADDRWORD) ds.node;	file->f_xops = 0;	return ENOERR;}// -------------------------------------------------------------------------// jffs3_chdir()// Change directory support.static int jffs3_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,		       cyg_dir * dir_out){	D2(printf("jffs3_chdir\n"));	if (dir_out != NULL) {		// This is a request to get a new directory pointer in		// *dir_out.		jffs3_dirsearch ds;		int err;		init_dirsearch(&ds, (struct _inode *) dir, name);		err = jffs3_find(&ds);		jffs3_iput(ds.dir);		if (err != ENOERR)			return err;		// check it is a directory		if (!S_ISDIR(ds.node->i_mode))			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.		jffs3_iput(node);	}	return ENOERR;}// -------------------------------------------------------------------------// jffs3_stat()// Get struct stat info for named object.static int jffs3_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name,		      struct stat *buf){	jffs3_dirsearch ds;	int err;	D2(printf("jffs3_stat\n"));	init_dirsearch(&ds, (struct _inode *) dir, name);	err = jffs3_find(&ds);	jffs3_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;	jffs3_iput(ds.node);	return ENOERR;}// -------------------------------------------------------------------------// jffs3_getinfo()// Getinfo. Currently only support pathconf().static int jffs3_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name,			 int key, void *buf, int len){	jffs3_dirsearch ds;	int err;	D2(printf("jffs3_getinfo\n"));	init_dirsearch(&ds, (struct _inode *) dir, name);	err = jffs3_find(&ds);	jffs3_iput(ds.dir);	if (err != ENOERR)		return err;	switch (key) {	case FS_INFO_CONF:		err = jffs3_pathconf(ds.node, (struct cyg_pathconf_info *) buf);		break;	default:		err = EINVAL;	}	jffs3_iput(ds.node);	return err;}// -------------------------------------------------------------------------// jffs3_setinfo()// Setinfo. Nothing to support here at present.static int jffs3_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("jffs3_setinfo\n"));	return EINVAL;}//==========================================================================// File operations// -------------------------------------------------------------------------// jffs3_fo_read()// Read data from the file.static int jffs3_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){	struct _inode *inode = (struct _inode *) fp->f_data;	struct jffs3_inode_info *f = JFFS3_INODE_INFO(inode);	struct jffs3_sb_info *c = JFFS3_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("jffs3_fo_read inode size %d\n", inode->i_size));		ret =		    jffs3_read_inode_range(c, f,					   (unsigned char *) iov->iov_base, pos,					   len);		if (ret) {			D1(printf			   ("jffs3_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_JFFS3_WRITE// -------------------------------------------------------------------------// jffs3_fo_write()// Write data to file.static int jffs3_extend_file (struct _inode *inode, struct jffs3_raw_inode *ri,		       unsigned long offset){	struct jffs3_sb_info *c = JFFS3_SB_INFO(inode->i_sb);	struct jffs3_inode_info *f = JFFS3_INODE_INFO(inode);	struct jffs3_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 = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);	if (ret)		return ret;	down(&f->sem);	ri->magic = cpu_to_je16(JFFS3_MAGIC_BITMASK);	ri->nodetype = cpu_to_je16(JFFS3_NODETYPE_INODE);	ri->totlen = cpu_to_je32(sizeof(*ri));	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs3_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 = JFFS3_COMPR_ZERO;	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));	ri->data_crc = cpu_to_je32(0);			fn = jffs3_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);	jffs3_complete_reservation(c);	if (IS_ERR(fn)) {		ret = PTR_ERR(fn);		up(&f->sem);		return ret;	}	ret = jffs3_add_full_dnode_to_inode(c, f, fn);	if (f->metadata) {		jffs3_mark_node_obsolete(c, f->metadata->raw);		jffs3_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));		jffs3_mark_node_obsolete(c, fn->raw);		jffs3_free_full_dnode(fn);		up(&f->sem);		return ret;	}	inode->i_size = offset;	up(&f->sem);	return 0;}static int jffs3_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 jffs3_raw_inode ri;	struct jffs3_inode_info *f = JFFS3_INODE_INFO(inode);	struct jffs3_sb_info *c = JFFS3_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 = jffs3_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];		char *buf = (char *) iov->iov_base;		off_t len = iov->iov_len;		uint32_t writtenlen;		int err;		D2(printf("jffs3_fo_write page_start_pos %d\n", pos));		D2(printf("jffs3_fo_write transfer size %d\n", l));		err = jffs3_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_JFFS3_WRITE */// -------------------------------------------------------------------------// jffs3_fo_lseek()// Seek to a new file position.static int jffs3_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("jffs3_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;	}        // Check that pos is still within current file size, or at the        // very end.        if (pos < 0 )                return EINVAL;	// All OK, set fp offset and return new position.	*apos = fp->f_offset = pos;	return ENOERR;}// -------------------------------------------------------------------------// jffs3_fo_ioctl()// Handle ioctls. Currently none are defined.static int jffs3_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com,			  CYG_ADDRWORD data){	// No Ioctls currenly defined.	D2(printf("jffs3_fo_ioctl\n"));	return EINVAL;}// -------------------------------------------------------------------------// jffs3_fo_fsync().// Force the file out to data storage.static int jffs3_fo_fsync(struct CYG_FILE_TAG *fp, int mode){	// Data is always permanently where it belongs, nothing to do	// here.	D2(printf("jffs3_fo_fsync\n"));	return ENOERR;}// -------------------------------------------------------------------------// jffs3_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 jffs3_fo_close(struct CYG_FILE_TAG *fp){	struct _inode *node = (struct _inode *) fp->f_data;	D2(printf("jffs3_fo_close\n"));	jffs3_iput(node);	fp->f_data = 0;		// zero data pointer	return ENOERR;}// -------------------------------------------------------------------------//jffs3_fo_fstat()// Get file status.static int jffs3_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf){	struct _inode *node = (struct _inode *) fp->f_data;	D2(printf("jffs3_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;}// -------------------------------------------------------------------------// jffs3_fo_getinfo()// Get info. Currently only supports fpathconf().static int jffs3_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("jffs3_fo_getinfo\n"));	switch (key) {	case FS_INFO_CONF:		err = jffs3_pathconf(node, (struct cyg_pathconf_info *) buf);		break;	default:		err = EINVAL;	}	return err;	return ENOERR;}// -------------------------------------------------------------------------// jffs3_fo_setinfo()// Set info. Nothing supported here.static int jffs3_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf,			    int len){	// No setinfo key supported at present	D2(printf("jffs3_fo_setinfo\n"));	return ENOERR;}//==========================================================================// Directory operations// -------------------------------------------------------------------------// jffs3_fo_dirread()// Read a single directory entry from a file.static __inline void filldir(char *nbuf, int nlen, const char *name, int namlen){	int len = nlen < namlen ? nlen : namlen;

⌨️ 快捷键说明

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