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

📄 fs-ecos.c

📁 带SD卡的LINUX根文件系统. 在ARM上应用
💻 C
📖 第 1 页 / 共 4 页
字号:
	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// ===============// ////==========================================================================struct page *read_cache_page(unsigned long index,			     int (*filler) (void *, struct page *), void *data){	// Only called in gc.c jffs2_garbage_collect_dnode	// but gets a real page for the specified inode	int err;	struct page *gc_page = malloc(sizeof (struct page));	printf("read_cache_page\n");	memset(&gc_buffer, 0, PAGE_CACHE_SIZE);	if (gc_page != NULL) {		gc_page->virtual = &gc_buffer;		gc_page->index = index;		err = filler(data, gc_page);		if (err < 0) {			free(gc_page);			gc_page = NULL;		}	}	return gc_page;}void page_cache_release(struct page *pg){	// Only called in gc.c jffs2_garbage_collect_dnode	// but should free the page malloc'd by read_cache_page	printf("page_cache_release\n");	free(pg);}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 = 0;	//1; // Let ecos manage the open count	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;}struct inode *iget(struct super_block *sb, cyg_uint32 ino){	// Substitute for iget drops straight through to reading the 	// inode from disk if it is not in the inode cache	// 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;	D2(printf("iget\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)			return inode;	}	inode = NULL;	// Not cached, so malloc it	inode = new_inode(sb);	if (inode == NULL)		return 0;	inode->i_ino = ino;	jffs2_read_inode(inode);	return inode;}void iput(struct inode *i){	// Called in dec_refcnt, jffs2_find 	// (and jffs2_open and jffs2_ops_mkdir?)	// super.c jffs2_read_super,	// and gc.c jffs2_garbage_collect_pass	struct inode *cached_inode;	D2(printf	   ("free iput inode %x $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n", i));	if (i && i->i_count) {		/* Added by dwmw2. iget/iput in Linux track the use count,		   don't just unconditionally free it */		printf("iput called for used inode\n");		return;	}	if (i != NULL) {		// Remove from the icache		for (cached_inode = i->i_sb->s_root; cached_inode != NULL;		     cached_inode = cached_inode->i_cache_next) {			if (cached_inode == i) {				cached_inode->i_cache_prev->i_cache_next = cached_inode->i_cache_next;	// Prveious entry points ahead of us				if (cached_inode->i_cache_next != NULL)					cached_inode->i_cache_next->i_cache_prev = cached_inode->i_cache_prev;	// Next entry points behind us				break;			}		}		// inode has been seperated from the cache		jffs2_clear_inode(i);		free(i);	}}static int return_EIO(void){	return -EIO;}#define EIO_ERROR ((void *) (return_EIO))void make_bad_inode(struct inode *inode){	// In readinode.c JFFS2 checks whether the inode has appropriate	// content for its marked type	D2(printf("make_bad_inode\n"));	inode->i_mode = S_IFREG;	inode->i_atime = inode->i_mtime = inode->i_ctime = cyg_timestamp();	inode->i_op = EIO_ERROR;	inode->i_fop = EIO_ERROR;}int is_bad_inode(struct inode *inode){	// Called in super.c jffs2_read_super,	// and gc.c jffs2_garbage_collect_pass	D2(printf("is_bad_inode\n"));	return (inode->i_op == EIO_ERROR);	/*if(i == NULL)	   return 1;	   return 0; */}cyg_bool jffs2_flash_read(struct jffs2_sb_info * c,			  cyg_uint32 read_buffer_offset, const size_t size,			  size_t * return_size, char *write_buffer){	Cyg_ErrNo err;	cyg_uint32 len = size;	struct super_block *sb = OFNI_BS_2SFFJ(c);	//D2(printf("FLASH READ\n"));	//D2(printf("read address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + read_buffer_offset));	//D2(printf("write address = %x\n", write_buffer));	//D2(printf("size = %x\n", size));	err = cyg_io_bread(sb->s_dev, write_buffer, &len, read_buffer_offset);	*return_size = (size_t) len;	return (err != ENOERR);}cyg_bool jffs2_flash_write(struct jffs2_sb_info * c,			   cyg_uint32 write_buffer_offset, const size_t size,			   size_t * return_size, char *read_buffer){	Cyg_ErrNo err;	cyg_uint32 len = size;	struct super_block *sb = OFNI_BS_2SFFJ(c);	//    D2(printf("FLASH WRITE ENABLED!!!\n"));	//    D2(printf("write address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + write_buffer_offset));	//    D2(printf("read address = %x\n", read_buffer));	//    D2(printf("size = %x\n", size));	err = cyg_io_bwrite(sb->s_dev, read_buffer, &len, write_buffer_offset);	*return_size = (size_t) len;	return (err != ENOERR);}intjffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs,		   unsigned long count, loff_t to, size_t * retlen){	unsigned long i;	size_t totlen = 0, thislen;	int ret = 0;	for (i = 0; i < count; i++) {		// writes need to be aligned but the data we're passed may not be		// Observation suggests most unaligned writes are small, so we		// optimize for that case.		if (((vecs[i].iov_len & (sizeof (int) - 1))) ||		    (((unsigned long) vecs[i].		      iov_base & (sizeof (unsigned long) - 1)))) {			// are there iov's after this one? Or is it so much we'd need			// to do multiple writes anyway?			if ((i + 1) < count || vecs[i].iov_len > 256) {				// cop out and malloc				unsigned long j;				ssize_t sizetomalloc = 0, totvecsize = 0;				char *cbuf, *cbufptr;				for (j = i; j < count; j++)					totvecsize += vecs[j].iov_len;				// pad up in case unaligned				sizetomalloc = totvecsize + sizeof (int) - 1;				sizetomalloc &= ~(sizeof (int) - 1);				cbuf = (char *) malloc(sizetomalloc);				// malloc returns aligned memory				if (!cbuf) {					ret = -ENOMEM;					goto writev_out;				}				cbufptr = cbuf;				for (j = i; j < count; j++) {					memcpy(cbufptr, vecs[j].iov_base,					       vecs[j].iov_len);					cbufptr += vecs[j].iov_len;				}				ret =				    jffs2_flash_write(c, to, sizetomalloc,						      &thislen, cbuf);				if (thislen > totvecsize)	// in case it was aligned up					thislen = totvecsize;				totlen += thislen;				free(cbuf);				goto writev_out;			} else {				// otherwise optimize for the common case				int buf[256 / sizeof (int)];	// int, so int aligned				size_t lentowrite;				lentowrite = vecs[i].iov_len;				// pad up in case its unaligned				lentowrite += sizeof (int) - 1;				lentowrite &= ~(sizeof (int) - 1);				memcpy(buf, vecs[i].iov_base, lentowrite);				ret =				    jffs2_flash_write(c, to, lentowrite,						      &thislen, (char *) &buf);				if (thislen > vecs[i].iov_len)					thislen = vecs[i].iov_len;			}	// else		} else			ret =			    jffs2_flash_write(c, to, vecs[i].iov_len, &thislen,					      vecs[i].iov_base);		totlen += thislen;		if (ret || thislen != vecs[i].iov_len)			break;		to += vecs[i].iov_len;	}      writev_out:	if (retlen)		*retlen = totlen;	return ret;}cyg_bool jffs2_flash_erase(struct jffs2_sb_info * c,			   struct jffs2_eraseblock * jeb){	cyg_io_flash_getconfig_erase_t e;	void *err_addr;	Cyg_ErrNo err;	cyg_uint32 len = sizeof (e);	struct super_block *sb = OFNI_BS_2SFFJ(c);	e.offset = jeb->offset;	e.len = c->sector_size;	e.err_address = &err_addr;	//        D2(printf("FLASH ERASE ENABLED!!!\n"));	//        D2(printf("erase address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + jeb->offset));	//        D2(printf("size = %x\n", c->sector_size));	err = cyg_io_get_config(sb->s_dev, CYG_IO_GET_CONFIG_FLASH_ERASE,				&e, &len);	return (err != ENOERR || e.flasherr != 0);}// -------------------------------------------------------------------------// EOF jffs2.cvoid 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) {		make_bad_inode(inode);		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;	insert_inode_hash(inode);	return inode;}void 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) {		make_bad_inode(inode);		up(&f->sem);		return;	}	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"));}

⌨️ 快捷键说明

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