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

📄 inode-v22.c

📁 mtd最新cvs jffs文件系统分析
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	/* Insert the new node into the file system.  */	if ((err = jffs_insert_node(c, 0, &raw_inode,				    dentry->d_name.name, node)) < 0) {		goto jffs_create_end;	}	/* Initialize an inode.  */	inode = jffs_new_inode(dir, &raw_inode, &err);	if (inode == NULL) {		goto jffs_create_end;	}	err = 0;	inode->i_op = &jffs_file_inode_operations;	inode->i_op->default_file_ops = &jffs_file_operations;	inode->i_nrpages = 0;	d_instantiate(dentry, inode); jffs_create_end:	D3(printk (KERN_NOTICE "create(): up biglock\n"));	up(&c->fmc->biglock);	return err;} /* jffs_create()  *//* Write, append or rewrite data to an existing file.  */static ssize_tjffs_file_write(struct file *filp, const char *buf, size_t count,	loff_t *ppos){	struct jffs_raw_inode raw_inode;	struct jffs_control *c;	struct jffs_file *f;	struct jffs_node *node;	struct inode *inode = filp->f_dentry->d_inode;	unsigned char *vbuf;	int recoverable = 0;	size_t written = 0;	__u32 thiscount = count;	loff_t pos;	int err = 0;		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 -EROFS;	}		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 (filp->f_flags & O_APPEND) {		pos = inode->i_size;	}	else {		pos = *ppos;	}		thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);		if (!(vbuf = kmalloc(thiscount, GFP_KERNEL))) {		D(printk("jffs_file_write(): failed to allocate bounce buffer. Fix me to use page cache\n"));		return -ENOMEM;	}	D3(printk (KERN_NOTICE "file_write(): down biglock\n"));	down(&c->fmc->biglock);		/* Urgh. POSIX says we can do short writes if we feel like it.	 * In practice, we can't. Nothing will cope. So we loop until	 * we're done.	 *	 * <_Anarchy_> posix and reality are not interconnected on this issue	 */	while (count) {		/* FIXME: This is entirely gratuitous use of bounce buffers.		   Get a clue and use the page cache.		   /me wanders off to get a crash course on Linux VFS		   dwmw2		*/		if (copy_from_user(vbuf, buf, thiscount)) {			err = -EFAULT;			goto out;		}				/* Things are going to be written so we could allocate and		   initialize the necessary data structures now.  */		if (!(node = jffs_alloc_node())) {			D(printk("jffs_file_write(): node == 0\n"));			err = -ENOMEM;			goto out;		}				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 = f->uid;		raw_inode.gid = f->gid;		raw_inode.atime = CURRENT_TIME;		raw_inode.mtime = raw_inode.atime;		raw_inode.ctime = f->ctime;		raw_inode.offset = pos;		raw_inode.dsize = thiscount;		raw_inode.rsize = 0;		raw_inode.nsize = f->nsize;		raw_inode.nlink = f->nlink;		raw_inode.spare = 0;		raw_inode.rename = 0;		raw_inode.deleted = 0;				if (pos < f->size) {			node->removed_size = raw_inode.rsize = min(thiscount, (__u32)f->size - pos));						/* If this node is going entirely over the top of old data,			   we can allow it to go into the reserved space, because			   we can that GC can reclaim the space later.			*/			if (pos + thiscount < f->size) {				/* If all the data we're overwriting are _real_,				   not just holes, then:				   recoverable = 1;				*/			}		}				/* Write the new node to the flash.  */		/* NOTE: We would be quite happy if jffs_write_node() wrote a		   smaller node than we were expecting. There's no need for it		   to waste the space at the end of the flash just because it's		   a little smaller than what we asked for. But that's a whole		   new can of worms which I'm not going to open this week. dwmw2.		*/		if ((err = jffs_write_node (c, node, &raw_inode, f->name,						(const unsigned char *)vbuf,						recoverable, f)) < 0) {			D(printk("jffs_file_write(): jffs_write_node() failed.\n"));			jffs_free_node(node);			goto out;		}				written += err;		buf += err;		count -= err;		pos += err;				/* Insert the new node into the file system.  */		if ((err = jffs_insert_node(c, f, &raw_inode, 0, node)) < 0) {			goto out;		}				D3(printk("jffs_file_write(): new f_pos %ld.\n", (long)pos));				thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);	}	out:	D3(printk (KERN_NOTICE "file_write(): up biglock\n"));	up(&c->fmc->biglock);	*ppos = pos;	kfree(vbuf);		/* Fix things in the real inode.  */	if (pos > inode->i_size) {		inode->i_size = pos;		inode->i_blocks = (inode->i_size + 511) >> 9;	}	inode->i_ctime = inode->i_mtime = CURRENT_TIME;	mark_inode_dirty(inode);	invalidate_inode_pages(inode);		/* What if there was an error, _and_ we've written some data. */	if (written)		return written;	else		return err;} /* 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 ret = 0;		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 -EIO;	}	D3(printk (KERN_NOTICE "ioctl(): down biglock\n"));	down(&c->fmc->biglock);		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 -- ");				if (!access_ok(VERIFY_WRITE,						(struct jffs_flash_status *)arg,						sizeof(struct jffs_flash_status))) {					D(printk("jffs_ioctl(): Bad arg in "							"JFFS_GET_STATUS ioctl!\n"));					ret = -EFAULT;					break;				}				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);				if (copy_to_user((struct jffs_flash_status *)arg,						&fst, sizeof(struct jffs_flash_status))) {					ret = -EFAULT;				}			}			break;		default:			ret = -ENOTTY;	}	D3(printk (KERN_NOTICE "ioctl(): up biglock\n"));	up(&c->fmc->biglock);	return ret;} /* jffs_ioctl()  */static int jffs_file_mmap(struct file *file, struct vm_area_struct *vma){	/* Don't allow shared writable mmaps - we don't handle them correctly */	if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))		return -EINVAL;		return generic_file_mmap(file, vma);} /* jffs_file_mmap() */static int jffs_fsync(struct file *f, struct dentry *d){	/* We currently have O_SYNC operations at all times.	   Do nothing.	*/	return 0;}static struct file_operations jffs_file_operations ={	read:  generic_file_read,    /* read */	write: jffs_file_write,      /* write */	ioctl: jffs_ioctl,           /* ioctl */	mmap:  jffs_file_mmap,    /* mmap */	fsync: jffs_fsync,};static struct inode_operations jffs_file_inode_operations ={	&jffs_file_operations,	lookup:  jffs_lookup,          /* lookup */	readpage: jffs_readpage,};static struct file_operations jffs_dir_operations ={	readdir: jffs_readdir,};static struct inode_operations jffs_dir_inode_operations ={	&jffs_dir_operations,	create:   jffs_create,	lookup:   jffs_lookup,	unlink:   jffs_unlink,	symlink:  jffs_symlink,	mkdir:    jffs_mkdir,	rmdir:    jffs_rmdir,	mknod:    jffs_mknod,	rename:   jffs_rename,};static struct inode_operations jffs_symlink_inode_operations ={	readlink:    jffs_readlink,	follow_link: jffs_follow_link,};/* 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;	D3(printk (KERN_NOTICE "read_inode(): down biglock\n"));	down(&c->fmc->biglock);	if (!(f = jffs_find_file(c, inode->i_ino))) {		D(printk("jffs_read_inode(): No such inode (%lu).\n",				inode->i_ino));		D3(printk (KERN_NOTICE "read_inode(): up biglock\n"));		up(&c->fmc->biglock);		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 = (inode->i_size + 511) >> 9;	if (S_ISREG(inode->i_mode)) {		inode->i_op = &jffs_file_inode_operations;		inode->i_op->default_file_ops = &jffs_file_operations;	}	else if (S_ISDIR(inode->i_mode)) {		inode->i_op = &jffs_dir_inode_operations;		inode->i_op->default_file_ops = &jffs_dir_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;	} else if (S_ISFIFO(inode->i_mode)) {		init_fifo(inode);	}		/* 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);	}	D3(printk (KERN_NOTICE "read_inode(): up biglock\n"));	up(&c->fmc->biglock);}voidjffs_delete_inode(struct inode *inode){	struct jffs_file *f;	struct jffs_control *c;	D3(printk("jffs_delete_inode(): inode->i_ino == %lu\n",			inode->i_ino));		lock_kernel();		inode->i_size = 0;	inode->i_blocks = 0;	clear_inode(inode);	if (inode->i_nlink == 0) {		c = (struct jffs_control *) inode->i_sb->u.generic_sbp;		f = (struct jffs_file *) jffs_find_file (c, inode->i_ino);		jffs_possibly_delete_file(f);	}		unlock_kernel();}voidjffs_write_super(struct super_block *sb){	struct jffs_control *c = (struct jffs_control *)sb->u.generic_sbp;		jffs_garbage_collect_trigger(c);}static struct super_operations jffs_ops ={	read_inode:    jffs_read_inode,	delete_inode:  jffs_delete_inode,	put_super:     jffs_put_super,	write_super:   jffs_write_super,	statfs:        jffs_statfs,	notify_change: jffs_notify_change,};static struct file_system_type jffs_fs_type ={	"jffs",	FS_REQUIRES_DEV,	jffs_read_super,	NULL};#ifdef MODULEEXPORT_NO_SYMBOLS;#define init_jffs_fs init_module#endifintinit_jffs_fs(void){	printk(KERN_INFO "JFFS version " JFFS_VERSION_STRING 	       ", (C) 1999, 2000 Axis Communications AB\n");	#ifdef CONFIG_JFFS_PROC_FS#ifdef KERNEL_VERSION /* Not defined for kernel 2.0.*.  */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)	jffs_proc_root = create_proc_entry ("jffs",			S_IFDIR | S_IRUGO | S_IXUGO, &proc_root_fs);#else	proc_register_dynamic(&proc_root_fs, &jffs_proc_root);#endif /* Linux version.  */#else	proc_register_dynamic(&proc_root_fs, &jffs_proc_root);#endif /* KERNEL_VERSION  */#endif /* CONFIG_JFFS_PROC_FS  */		fm_cache = kmem_cache_create("jffs_fm", sizeof(struct jffs_fm),				     0, SLAB_HWCACHE_ALIGN, NULL, NULL);	node_cache = kmem_cache_create("jffs_node",sizeof(struct jffs_node),			0, SLAB_HWCACHE_ALIGN, NULL, NULL);		return register_filesystem(&jffs_fs_type);}#ifdef MODULEvoid cleanup_module(void){	unregister_filesystem(&jffs_fs_type);	kmem_cache_destroy(fm_cache);	kmem_cache_destroy(node_cache);}#endif

⌨️ 快捷键说明

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