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

📄 inode.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
	*res_inode = 0;	if (!dir) {		dir = current->fs->root;		dir->i_count++;	}	if (!inode) {		iput(dir);		return -ENOENT;	}	if (!S_ISLNK(inode->i_mode)) {		*res_inode = inode;		iput(dir);		return 0;	}	if (current->link_count > 5) {		iput(inode);		iput(dir);		return -ELOOP;	}	f = (struct jffs_file *)inode->u.generic_ip;	if (!(link = (char *)kmalloc(f->size + 1, GFP_KERNEL))) {		D(printk("jffs_follow_link(): kmalloc() failed.\n"));		iput(inode);		iput(dir);		return -ENOMEM;	}	r = jffs_read_data(f, link, 0, f->size);	if (r < f->size) {		D(printk("jffs_follow_link(): Failed to read symname.\n"));		kfree(link);		iput(inode);		iput(dir);		return -EIO;	}	link[r] = '\0';	UPDATE_ATIME(inode);	current->link_count++;	r = open_namei(link, flag, mode, res_inode, dir);	current->link_count--;	kfree(link);	iput(inode);	return r;} /* jffs_follow_link()  *//* Create an inode inside a JFFS directory (dir) and return it.  */static intjffs_create(struct inode *dir, const char *name, int len,            int mode, struct inode **result){	struct jffs_raw_inode raw_inode;	struct jffs_control *c;	struct jffs_node *node;	struct jffs_file *dir_f; /* JFFS representation of the directory.  */	struct inode *inode;	*result = (struct inode *)0;	D1({		char *s = (char *)kmalloc(len + 1, GFP_KERNEL);		memcpy(s, name, len);		s[len] = '\0';		printk("jffs_create(): dir: 0x%p, name: \"%s\"\n", dir, s);		kfree(s);	});	if (!dir) {		return -ENOENT;	}	if (len > JFFS_MAX_NAME_LEN) {		iput(dir);		return -ENAMETOOLONG;	}	dir_f = (struct jffs_file *)dir->u.generic_ip;	ASSERT(if (!dir_f) {		printk(KERN_ERR "jffs_create(): No reference to a "		       "jffs_file struct in inode.\n");		iput(dir);		return -1;	});	c = dir_f->c;	if (!JFFS_ENOUGH_SPACE(c->fmc)) {		D1(printk("jffs_create(): 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"));		iput(dir);		return -ENOSPC;	}	/* If there already exists a file or directory with the same name,	   then this operation should fail. I originally thought that VFS	   should take care of this issue.  */	if (jffs_find_child(dir_f, name, len)) {		D(printk("jffs_create(): There already exists a file or "			 "directory named \"%s\"!\n", name));		iput(dir);		return -EEXIST;	}	/* Create a node and initialize as much as needed.  */	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),						  GFP_KERNEL))) {		D(printk("jffs_create(): Allocation failed: node == 0\n"));		iput(dir);		return -ENOMEM;	}	DJM(no_jffs_node++);	node->data_offset = 0;	node->removed_size = 0;	/* Initialize the raw inode.  */	raw_inode.magic = JFFS_MAGIC_BITMASK;	raw_inode.ino = c->next_ino++;	raw_inode.pino = dir_f->ino;	raw_inode.version = 1;	raw_inode.mode = 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 = raw_inode.atime;	raw_inode.offset = 0;	raw_inode.dsize = 0;	raw_inode.rsize = 0;	raw_inode.nsize = len;	raw_inode.nlink = 1;	raw_inode.spare = 0;	raw_inode.rename = 0;	raw_inode.deleted = 0;	/* Write the new node to the flash.  */	if (jffs_write_node(c, node, &raw_inode, name, 0) < 0) {		D(printk("jffs_create(): jffs_write_node() failed.\n"));		kfree(node);		DJM(no_jffs_node--);		iput(dir);		return -1;	}	/* Insert the new node into the file system.  */	if (jffs_insert_node(c, 0, &raw_inode, name, node) < 0) {		iput(dir);		return -1;	}	/* Initialize an inode.  */	if (!(inode = get_empty_inode())) {		iput(dir);		return -1;	}	inode->i_dev = dir->i_sb->s_dev;	inode->i_ino = raw_inode.ino;	inode->i_mode = mode;	inode->i_nlink = raw_inode.nlink;	inode->i_uid = raw_inode.uid;	inode->i_gid = raw_inode.gid;	inode->i_rdev = 0;	inode->i_size = 0;	inode->i_atime = raw_inode.atime;	inode->i_mtime = raw_inode.mtime;	inode->i_ctime = raw_inode.ctime;	inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */	inode->i_blocks = 0;	inode->i_version = 0;	inode->i_nrpages = 0;	/*inode->i_sem = 0;*/	inode->i_op = &jffs_file_inode_operations;	inode->i_sb = dir->i_sb;	inode->i_wait = 0;	inode->i_flock = 0;	inode->i_count = 1;	inode->i_flags = dir->i_sb->s_flags;	inode->i_dirt = 1;	inode->u.generic_ip = (void *)jffs_find_file(c, raw_inode.ino);	iput(dir);	*result = inode;	return 0;} /* jffs_create()  *//* Write, append or rewrite data to an existing file.  */static intjffs_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"));		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;	}	DJM(no_jffs_node++);	node->data_offset = f->size;	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 = f->size;	raw_inode.dsize = count;	raw_inode.rsize = 0;	raw_inode.nsize = 0;	raw_inode.nlink = f->nlink;	raw_inode.spare = 0;	raw_inode.rename = 0;	raw_inode.deleted = 0;	/* Write the new node to the flash.  */	if ((written = jffs_write_node(c, node, &raw_inode, 0,				       (const unsigned char *)buf)) < 0) {		D(printk("jffs_file_write(): jffs_write_node() failed.\n"));		kfree(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;	return written;} /* jffs_file_write()  *//* This is our ioctl() routine.  */static intjffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,	   unsigned long arg){	struct jffs_control *c;	int err;	D2(printk("***jffs_ioctl(): cmd = 0x%08x, arg = 0x%08lx\n", cmd, arg));	if (!(c = (struct jffs_control *)inode->i_sb->u.generic_sbp)) {		printk(KERN_ERR "JFFS: Bad inode in ioctl() call. "		       "(cmd = 0x%08x)\n", cmd);		return -1;	}	switch (cmd) {	case JFFS_PRINT_HASH:		jffs_print_hash_table(c);		break;	case JFFS_PRINT_TREE:		jffs_print_tree(c->root, 0);		break;	case JFFS_GET_STATUS:		{			struct jffs_flash_status fst;			struct jffs_fmcontrol *fmc = c->fmc;			printk("Flash status -- ");			err = verify_area(VERIFY_WRITE,					  (struct jffs_flash_status *)arg,					  sizeof(struct jffs_flash_status));			if (err) {				D(printk("jffs_ioctl(): Bad arg in "					 "JFFS_GET_STATUS ioctl!\n"));				return err;			}			fst.size = fmc->flash_size;			fst.used = fmc->used_size;			fst.dirty = fmc->dirty_size;			fst.begin = fmc->head->offset;			fst.end = fmc->tail->offset + fmc->tail->size;			printk("size: %d, used: %d, dirty: %d, "			       "begin: %d, end: %d\n",			       fst.size, fst.used, fst.dirty,			       fst.begin, fst.end);			memcpy_tofs((struct jffs_flash_status *)arg, &fst,				    sizeof(struct jffs_flash_status));		}		break;	default:		return -ENOTTY;	}	return 0;} /* jffs_ioctl()  */static struct file_operations jffs_file_operations ={	NULL,                 /* lseek - default */	generic_file_read,    /* read */	jffs_file_write,      /* write */	NULL,                 /* readdir */	NULL,                 /* select - default */	jffs_ioctl,           /* ioctl */	generic_file_mmap,    /* 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 */	jffs_lookup,          /* lookup */	NULL,                 /* link */	NULL,                 /* unlink */	NULL,                 /* symlink */	NULL,                 /* mkdir */	NULL,                 /* rmdir */	NULL,                 /* mknod */	NULL,                 /* rename */	NULL,                 /* readlink */	NULL,                 /* follow_link */	jffs_readpage,        /* 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 */	NULL,                 /* ioctl */	NULL,                 /* mmap */	NULL,                 /* open */	NULL,                 /* release */	NULL,                 /* fsync */	NULL,                 /* fasync */	NULL,                 /* check_media_change */	NULL                  /* revalidate */};static struct inode_operations jffs_dir_inode_operations ={	&jffs_dir_operations,	jffs_create,           /* create */	jffs_lookup,           /* lookup */	NULL,                  /* link */	jffs_unlink,           /* unlink */	jffs_symlink,          /* symlink */	jffs_mkdir,            /* mkdir */	jffs_rmdir,            /* rmdir */	jffs_mknod,            /* mknod */	jffs_rename,           /* rename */	NULL,                  /* readlink */	NULL,                  /* follow_link */	NULL,                  /* readpage */	NULL,                  /* writepage */	NULL,                  /* bmap */	NULL,                  /* truncate */	NULL,                  /* permission */	NULL                   /* smap */};static struct inode_operations jffs_symlink_inode_operations ={	NULL,                  /* No file operations.  */	NULL,                  /* create */	NULL,                  /* lookup */	NULL,                  /* link */	NULL,                  /* unlink */	NULL,                  /* symlink */	NULL,                  /* mkdir */	NULL,                  /* rmdir */	NULL,                  /* mknod */	NULL,                  /* rename */	jffs_readlink,         /* readlink */	jffs_follow_link,      /* follow_link */	NULL,                  /* readpage */	NULL,                  /* writepage */	NULL,                  /* bmap */	NULL,                  /* truncate */	NULL,                  /* permission */	NULL                   /* smap */};/* Initialize an inode for the VFS.  */static voidjffs_read_inode(struct inode *inode){	struct jffs_file *f;	struct jffs_control *c;	D3(printk("jffs_read_inode(): inode->i_ino == %lu\n", inode->i_ino));	if (!inode->i_sb) {		D(printk("jffs_read_inode(): !inode->i_sb ==> "			 "No super block!\n"));		return;	}	c = (struct jffs_control *)inode->i_sb->u.generic_sbp;	if (!(f = jffs_find_file(c, inode->i_ino))) {		D(printk("jffs_read_inode(): No such inode (%lu).\n",			 inode->i_ino));		return;	}	inode->u.generic_ip = (void *)f;	inode->i_mode = f->mode;	inode->i_nlink = f->nlink;	inode->i_uid = f->uid;	inode->i_gid = f->gid;	inode->i_size = f->size;	inode->i_atime = f->atime;	inode->i_mtime = f->mtime;	inode->i_ctime = f->ctime;	inode->i_blksize = PAGE_SIZE;	inode->i_blocks = 0;	if (S_ISREG(inode->i_mode)) {		inode->i_op = &jffs_file_inode_operations;	}	else if (S_ISDIR(inode->i_mode)) {		inode->i_op = &jffs_dir_inode_operations;	}	else if (S_ISLNK(inode->i_mode)) {                inode->i_op = &jffs_symlink_inode_operations;	}	else if (S_ISCHR(inode->i_mode)) {		inode->i_op = &chrdev_inode_operations;	}	else if (S_ISBLK(inode->i_mode)) {		inode->i_op = &blkdev_inode_operations;	}	/* If the node is a device of some sort, then the number of the	   device should be read from the flash memory and then added	   to the inode's i_rdev member.  */	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {		kdev_t rdev;		jffs_read_data(f, (char *)&rdev, 0, sizeof(kdev_t));		inode->i_rdev = kdev_t_to_nr(rdev);	}}voidjffs_write_super(struct super_block *sb){#ifdef USE_GC	jffs_garbage_collect((struct jffs_control *)sb->u.generic_sbp);#endif}static struct super_operations jffs_ops ={	jffs_read_inode,    /* read inode */	jffs_notify_change, /* notify change */	NULL,               /* write inode */	NULL,               /* put inode */	jffs_put_super,     /* put super */	jffs_write_super,   /* write super */	jffs_statfs,        /* statfs */	NULL                /* remount */};static struct file_system_type jffs_fs_type ={	jffs_read_super,	"jffs",	1,	NULL};intinit_jffs_fs(void){	printk("JFFS "#if defined(JFFS_FLASH_SHORTCUT) && JFFS_FLASH_SHORTCUT	       "(Flash Shortcut) "#endif	       "version " JFFS_VERSION_STRING	       ", (C) 1999, 2000  Axis Communications AB\n");	return register_filesystem(&jffs_fs_type);}#ifdef MODULEintinit_module(void){	int status;	if ((status = init_jffs_fs()) == 0) {		register_symtab(0);	}	return status;}voidcleanup_module(void){	unregister_filesystem(&jffs_fs_type);}#endif

⌨️ 快捷键说明

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