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

📄 j_inode.cpp

📁 JFFS的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//#include "..\..\lib\lib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mytypes.h>
#include <io.h>				//livefall
#include "../jffs/fileext.h"
//#include "..\..\comm\cmd.h"
#include "../jffs/jffstypes.h"
#include "../jffs/fs.h"
#include "../jffs/errno.h"
#include "../jffs/stat.h"
#include "../jffs/fcntl.h"
#include "../jffs/ioctl.h"
#include "../jffs/jffs.h"
#include "../jffs/jffs_fm.h"
#include "../jffs/j_intrep.h"

#if defined(CONFIG_JFFS_FS_VERBOSE) && CONFIG_JFFS_FS_VERBOSE
#define D(x) x
#else
#define D(x)
#endif
#define D1(x)
#define D2(x)
#define D3(x)
#define ASSERT(x)

#define printk printf

extern unsigned long CURRENT_TIME;
struct inode I_FLASH;	/*需填写*/
struct super_block SB_FLASH;

static int jffs_file_read(struct inode *inode, struct file *filp, char *buf, int count);
static int jffs_file_write(struct inode *inode, struct file *filp, const char *buf, int count);
static int jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
static int jffs_readdir(struct inode *dir, struct file *filp, void *dirent, filldir_t filldir);
static int jffs_create(struct inode *dir, const char *name, int len, int mode, struct inode **result);
static int jffs_lookup(struct inode *dir, const char *name, int len, struct inode **result);
static int jffs_unlink(struct inode *dir, const char *name, int len);
static int jffs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev);
int jffs_rename(struct inode *old_dir, const char *old_name, int old_len,
            struct inode *new_dir, const char *new_name, int new_len, int must_be_dir);
static struct super_block *jffs_read_super(struct super_block *sb, void *data, int silent);
static int jffs_mkdir(struct inode *dir, const char *name, int len, int mode);
                
static struct file_operations jffs_file_operations =
{
	NULL,                 /* lseek - default */
	jffs_file_read,   	  /* read ?????*/
	jffs_file_write,      /* write */
	NULL,                 /* readdir */
	NULL,                 /* select - default */
	jffs_ioctl,           /* ioctl */
	NULL,    			  /* mmap */
	NULL,                 /* open */
	NULL,                 /* release */
	NULL,                 /* fsync */
	NULL,                 /* fasync */
	NULL,                 /* check_media_change */
	NULL                  /* revalidate */
};

static struct inode_operations jffs_file_inode_operations =
{
	&jffs_file_operations,
	NULL,                 /* create */
	NULL,       		  /* lookup??? */
	NULL,                 /* link */
	NULL,                 /* unlink */
	NULL,                 /* symlink */
	NULL,                 /* mkdir */
	NULL,                 /* rmdir */
	NULL,                 /* mknod */
	NULL,                 /* rename */
	NULL,                 /* readlink */
	NULL,                 /* follow_link */
	NULL,        		  /* readpage */
	NULL,                 /* writepage */
	NULL,                 /* bmap -- not really */
	NULL,                 /* truncate */
	NULL,                 /* permission */
	NULL                  /* smap */
};

static struct file_operations jffs_dir_operations =
{
	NULL,                 /* lseek - default */
	NULL,                 /* read */
	NULL,                 /* write */
	jffs_readdir,         /* readdir */
	NULL,                 /* select - default */
	jffs_ioctl,           /* ioctl */
	NULL,                 /* mmap */
	NULL,                 /* open */
	NULL,                 /* release */
	NULL,                 /* fsync */
	NULL,                 /* fasync */
	NULL,                 /* check_media_change */
	NULL                  /* revalidate */
};

struct inode_operations jffs_dir_inode_operations =
{
	&jffs_dir_operations,
	jffs_create,           /* create */
	jffs_lookup,           /* lookup */
	NULL,                  /* link */
	jffs_unlink,           /* unlink !!!文件删除*/
	NULL,                  /* symlink */
	jffs_mkdir,            /* mkdir */
	NULL,            	   /* rmdir */
	jffs_mknod,            /* mknod ???与create有何区别 */
	jffs_rename,           /* rename */
	NULL,                  /* readlink */
	NULL,                  /* follow_link */
	NULL,                  /* readpage */
	NULL,                  /* writepage */
	NULL,                  /* bmap */
	NULL,                  /* truncate */
	NULL,                  /* permission */
	NULL                   /* smap */
};

/*TODO*/
static struct super_operations jffs_ops =
{
	NULL, /*jffs_read_inode,*/    /* read inode */
	NULL, /*jffs_notify_change,*/ /* notify change */
	NULL,               /* write inode */
	NULL,               /* put inode */
	NULL, /*jffs_put_super,*/     /* put super */
	NULL, /*jffs_write_super,*/   /* write super */
	NULL, /*jffs_statfs,*/        /* statfs */
	NULL                /* remount */
};

int init_jffs_fs(void)
{
	/*填充flash目录; 扫描flash; 垃圾清除*/
	/*TODO*/
	jffs_read_super(&SB_FLASH, NULL, 0);
	return 0;
}

/* Find a file in a directory. If the file exists, return its
   corresponding inode in the argument `result'.  */
static int jffs_lookup(struct inode *dir, const char *name, int len, struct inode **result)
{
	struct jffs_file *d;
	struct jffs_file *f;
	struct inode * empty = NULL;

	int r = 0;

	D3({
		char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
		memcpy(s, name, len);
		s[len] = '\0';
		printk("jffs_lookup(): dir: 0x%p, name: \"%s\"\n", dir, s);
		kfree(s);
	});

	*result = (struct inode *)0;
	if (!dir) {
		return -ENOENT;
	}
	if (!S_ISDIR(dir->i_mode)) {
		r = -ENOTDIR;
		goto jffs_lookup_end;
	}
	if (len > JFFS_MAX_NAME_LEN) {
		r = -ENAMETOOLONG;
		goto jffs_lookup_end;
	}

	if (!(d = (struct jffs_file *)dir->u.generic_ip)) {
		D(printk("jffs_lookup(): No such inode! (%lu)\n",
			 dir->i_ino));
		r = -ENOENT;
		goto jffs_lookup_end;
	}

	/* Get the corresponding inode to the file.  */
	if ((f = jffs_find_child(d, name, len))) {
		/*if (!(*result = iget(dir->i_sb, f->ino))) {
			D(printk("jffs_lookup(): iget() ==> NULL\n"));
			r = -ENOENT;
		}*/
		empty = get_empty_inode();
		empty->i_sb = dir->i_sb;
		empty->i_dev = 0;/*sb->s_dev;*/
		empty->i_ino = f->ino;
		empty->i_flags =0; /*sb->s_flags;*/

		/*amine: 2002-09-08*/
		if (S_ISDIR(f->mode)) {
			empty->i_mode = S_IFDIR;
			empty->i_op = &jffs_dir_inode_operations;
		}
		else
			empty->i_op = &jffs_file_inode_operations;
		/*empty->i_op = &jffs_file_inode_operations;*/
		
		empty->i_size = f->size; 
		empty->u.generic_ip = (void *)f;
		*result = empty;
	}
	else {
		D3(printk("jffs_lookup(): Couldn't find the file. "
			  "f = 0x%p, name = \"%s\", d = 0x%p, d->ino = %u\n",
			  f, name, d, d->ino));
		r = -ENOENT;
	}

jffs_lookup_end:
	/*iput(dir);*/
	return r;
} /* jffs_lookup()  */

int jffs_min(int a, int b);
int jffs_write_node(struct jffs_control *c, struct jffs_node *node,
		struct jffs_raw_inode *raw_inode,
		const char *name, const unsigned char *data);
int jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
		 const struct jffs_raw_inode *raw_inode,
		 const char *name, struct jffs_node *node);	

/* Write, append or rewrite data to an existing file.  */
static int jffs_file_write(struct inode *inode, struct file *filp,
                const char *buf, int count)
{
	struct jffs_raw_inode raw_inode;
	struct jffs_control *c;
	struct jffs_file *f;
	struct jffs_node *node;
	int written = 0;
	int pos;

	D2(printk("***jffs_file_write(): inode: 0x%p (ino: %lu), "
		  "filp: 0x%p, buf: 0x%p, count: %d\n",
		  inode, inode->i_ino, filp, buf, count));

	if (!inode) {
		D(printk("jffs_file_write(): inode == NULL\n"));
		return -EINVAL;
	}

	/*if (inode->i_sb->s_flags & MS_RDONLY) {
		D(printk("jffs_file_write(): MS_RDONLY\n"));
		return -ENOSPC;
	}*/
	/*if (!S_ISREG(inode->i_mode)) {
		D(printk("jffs_file_write(): inode->i_mode == 0x%08x\n",
			 inode->i_mode));
		return -EINVAL;
	}*/

	if (!(f = (struct jffs_file *)inode->u.generic_ip)) {
		D(printk("jffs_file_write(): inode->u.generic_ip = 0x%p\n",
			 inode->u.generic_ip));
		return -EINVAL;
	}
	c = f->c;

	if (!JFFS_ENOUGH_SPACE(c->fmc)) {
		D1(printk("jffs_file_write(): Free size = %u\n",
			  jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
		//D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
		D(printk("jffs_file_write: No space left on device\n"));
		return -ENOSPC;
	}

	if (filp->f_flags & O_APPEND) {
		pos = inode->i_size;
	}
	else {
		pos = filp->f_pos;
	}

	/* Things are going to be written so we could allocate and
	   initialize the necessary data structures now.  */
	/*if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
						  GFP_KERNEL))) {
		D(printk("jffs_file_write(): node == 0\n"));
		return -ENOMEM;
	}*/
	if ( !(node = (struct jffs_node *) malloc(sizeof(struct jffs_node))) ) {
		D(printk("jffs_file_write(): node == 0\n"));
		return -ENOMEM;
	}

	DJM(no_jffs_node++);
	node->data_offset = pos;
	node->removed_size = 0;

	/* Initialize the raw inode.  */
	raw_inode.magic = JFFS_MAGIC_BITMASK;
	raw_inode.ino = f->ino;
	raw_inode.pino = f->pino;
	raw_inode.version = f->highest_version + 1;
	raw_inode.mode = f->mode;
	/*raw_inode.uid = current->fsuid;
	raw_inode.gid = current->fsgid;*/
	raw_inode.atime = CURRENT_TIME;
	raw_inode.mtime = raw_inode.atime;
	raw_inode.ctime = f->ctime;
	raw_inode.offset = pos;
	raw_inode.dsize = count;
	raw_inode.rsize = 0;
	raw_inode.nsize = f->nsize; //fname
	raw_inode.nlink = f->nlink;
	raw_inode.spare = 0;
	raw_inode.rename = 0;
	raw_inode.deleted = 0;

	if (pos < f->size) {
		raw_inode.rsize = jffs_min(f->size - pos, count);
		node->removed_size = raw_inode.rsize;
	}

	/* Write the new node to the flash.  */
	if ((written = jffs_write_node(c, node, &raw_inode, f->name, //fname
				       (const unsigned char *)buf)) < 0) {
		D(printk("jffs_file_write(): jffs_write_node() failed.\n"));
		free(node);
		DJM(no_jffs_node--);
		return -1;
	}

	/* Insert the new node into the file system.  */
	if (jffs_insert_node(c, f, &raw_inode, 0, node) < 0) {
		return -1;
	}
	pos += written;
	filp->f_pos = pos;

	D3(printk("jffs_file_write(): new f_pos %d.\n", pos));

	/* Fix things in the real inode.  */
	if (pos > inode->i_size) {
		inode->i_size = pos;
	}
	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
	inode->i_dirt = 1;

	/* simonk: fixes the O_APPEND bug, but forces a buffer flush.
	   Should probably use update_vm_cache() instead.  */
	/*invalidate_inode_pages(inode);*/

	return written;
} /* jffs_file_write()  */

/*从文件中读取数据,自己编写*/
static int jffs_file_read(struct inode *inode, struct file *filp,
                char *buf, int count)
{
	int ret;
	
	struct jffs_file *f = (struct jffs_file *)inode->u.generic_ip;
	
	ret = jffs_read_data(f, (char *)buf, filp->f_pos, count);
	
	if(ret > 0)	filp->f_pos += ret;
	
	return ret;
}

/*从当前偏移剪切size长度, 参照jffs_file_write, 原jffs这工作由jffs_notify_change完成*/
static int jffs_file_trunc(struct inode *inode, struct file *filp, int count)
{
	struct jffs_raw_inode raw_inode;
	struct jffs_control *c;
	struct jffs_file *f;
	struct jffs_node *node;
	int written = 0;
	int pos;

	D2(printk("***jffs_file_write(): inode: 0x%p (ino: %lu), "
		  "filp: 0x%p, buf: 0x%p, count: %d\n",
		  inode, inode->i_ino, filp, buf, count));

	if (!inode) {
		D(printk("jffs_file_write(): inode == NULL\n"));
		return -EINVAL;
	}

	/*if (inode->i_sb->s_flags & MS_RDONLY) {
		D(printk("jffs_file_write(): MS_RDONLY\n"));
		return -ENOSPC;
	}*/
	/*if (!S_ISREG(inode->i_mode)) {
		D(printk("jffs_file_write(): inode->i_mode == 0x%08x\n",
			 inode->i_mode));
		return -EINVAL;
	}*/

	if (!(f = (struct jffs_file *)inode->u.generic_ip)) {
		D(printk("jffs_file_write(): inode->u.generic_ip = 0x%p\n",
			 inode->u.generic_ip));
		return -EINVAL;
	}
	c = f->c;

	/*if (!JFFS_ENOUGH_SPACE(c->fmc)) {
		D1(printk("jffs_file_write(): Free size = %u\n",
			  jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
		D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
		return -ENOSPC;
	}*/

	/*if (filp->f_flags & O_APPEND) {
		pos = inode->i_size;
	}
	else {
		pos = filp->f_pos;
	}*/
	pos = filp->f_pos;

	/* Things are going to be written so we could allocate and
	   initialize the necessary data structures now.  */
	/*if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),

⌨️ 快捷键说明

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