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

📄 fs-ecos.c

📁 带SD卡的LINUX根文件系统. 在ARM上应用
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (err == 0)		ds1.node->i_ctime =		    ds2.dir->i_ctime = ds2.dir->i_mtime = cyg_timestamp();	return err;}// -------------------------------------------------------------------------// jffs2_opendir()// Open a directory for reading.static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name,			 cyg_file * file){	jffs2_dirsearch ds;	int err;	D2(printf("jffs2_opendir\n"));	icache_evict((struct inode *) mte->root, (struct inode *) dir);	init_dirsearch(&ds, (struct inode *) dir, name);	err = jffs2_find(&ds);	if (err != ENOERR)		return err;	// check it is really a directory.	if (!S_ISDIR(ds.node->i_mode))		return ENOTDIR;	ds.node->i_count++;	// Count successful open	// 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 = &jffs2_dirops;	file->f_offset = 0;	file->f_data = (CYG_ADDRWORD) ds.node;	file->f_xops = 0;	return ENOERR;}// -------------------------------------------------------------------------// 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;		icache_evict((struct inode *) mte->root, (struct inode *) dir);		init_dirsearch(&ds, (struct inode *) dir, name);		err = jffs2_find(&ds);		if (err != ENOERR)			return err;		// check it is a directory		if (!S_ISDIR(ds.node->i_mode))			return ENOTDIR;		// Increment ref count to keep this directory in existance		// while it is the current cdir.		ds.node->i_count++;		// 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.		dec_refcnt(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"));	icache_evict((struct inode *) mte->root, (struct inode *) dir);	init_dirsearch(&ds, (struct inode *) dir, name);	err = jffs2_find(&ds);	if (err != ENOERR)		return err;	// Fill in the status	buf->st_mode = ds.node->i_mode;	buf->st_ino = (ino_t) ds.node;	buf->st_dev = 0;	buf->st_nlink = ds.node->i_nlink;	buf->st_uid = 0;	buf->st_gid = 0;	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;	return err;	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"));	icache_evict((struct inode *) mte->root, (struct inode *) dir);	init_dirsearch(&ds, (struct inode *) dir, name);	err = jffs2_find(&ds);	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;	}	return err;	return ENOERR;}// -------------------------------------------------------------------------// 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;}// -------------------------------------------------------------------------// jffs2_fo_write()// Write data to file.static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio){	struct page write_page;	off_t page_start_pos;	struct inode *node = (struct inode *) fp->f_data;	off_t pos = fp->f_offset;	ssize_t resid = uio->uio_resid;	int i;	memset(&read_write_buffer, 0, PAGE_CACHE_SIZE);	write_page.virtual = &read_write_buffer;	// 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 = node->i_size;	// Check that pos is within current file size, or at the very end.	if (pos < 0 || pos > node->i_size)		return EINVAL;	// 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;		// loop over the vector writing it to the file until it has		// all been done.		while (len > 0) {			//cyg_uint8 *fbuf;			//size_t bsize;			size_t writtenlen;			off_t l = len;			int err;			write_page.index = 0;			page_start_pos = pos;			while (page_start_pos >= (PAGE_CACHE_SIZE)) {				write_page.index++;				page_start_pos -= PAGE_CACHE_SIZE;			}			if (l > PAGE_CACHE_SIZE - page_start_pos)				l = PAGE_CACHE_SIZE - page_start_pos;			D2(printf			   ("jffs2_fo_write write_page.index %d\n",			    write_page.index));			D2(printf			   ("jffs2_fo_write page_start_pos %d\n",			    page_start_pos));			D2(printf("jffs2_fo_write transfer size %d\n", l));			err =			    jffs2_prepare_write(node, &write_page,						page_start_pos,						page_start_pos + l);			if (err != 0)				return err;			// copy data in			memcpy(&read_write_buffer[page_start_pos], buf, l);			writtenlen =			    jffs2_commit_write(node, &write_page,					       page_start_pos,					       page_start_pos + l);			if (writtenlen != l)				return ENOSPC;			// Update working vars			len -= l;			buf += l;			pos += l;			resid -= l;		}	}	// We wrote some data successfully, update the modified and access	// times of the node, increase its size appropriately, and update	// the file offset and transfer residue.	node->i_mtime = node->i_ctime = cyg_timestamp();	if (pos > node->i_size)		node->i_size = pos;	uio->uio_resid = resid;	fp->f_offset = pos;	return ENOERR;}// -------------------------------------------------------------------------// 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;	}	// Check that pos is still within current file size, or at the	// very end.	if (pos < 0 || pos > node->i_size)		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"));	dec_refcnt(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 = (ino_t) node;	buf->st_dev = 0;	buf->st_nlink = node->i_nlink;	buf->st_uid = 0;	buf->st_gid = 0;	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	D2(printf("jffs2_fo_setinfo\n"));	return ENOERR;}//==========================================================================// Directory operations// -------------------------------------------------------------------------// jffs2_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;	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;

⌨️ 快捷键说明

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