inode-v23.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,848 行 · 第 1/4 页

C
1,848
字号
	ret = jffs_remove(dir, dentry, S_IFDIR);	D3(printk (KERN_NOTICE "rmdir(): up biglock\n"));	up(&c->fmc->biglock);	unlock_kernel();	return ret;}/* Remove any kind of file except for directories.  */static intjffs_unlink(struct inode *dir, struct dentry *dentry){	struct jffs_control *c = (struct jffs_control *)dir->i_sb->s_fs_info;	int ret; 	lock_kernel();	D3(printk("***jffs_unlink()\n"));	D3(printk (KERN_NOTICE "unlink(): down biglock\n"));	down(&c->fmc->biglock);	ret = jffs_remove(dir, dentry, 0);	D3(printk (KERN_NOTICE "unlink(): up biglock\n"));	up(&c->fmc->biglock);	unlock_kernel();	return ret;}/* Remove a JFFS entry, i.e. plain files, directories, etc.  Here we   shouldn't test for free space on the device.  */static intjffs_remove(struct inode *dir, struct dentry *dentry, int type){	struct jffs_raw_inode raw_inode;	struct jffs_control *c;	struct jffs_file *dir_f; /* The file-to-remove's parent.  */	struct jffs_file *del_f; /* The file to remove.  */	struct jffs_node *del_node;	struct inode *inode = NULL;	int result = 0;	D1({		int len = dentry->d_name.len;		const char *name = dentry->d_name.name;		char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);		memcpy(_name, name, len);		_name[len] = '\0';		printk("***jffs_remove(): file = \"%s\", ino = %ld\n", _name, dentry->d_inode->i_ino);		kfree(_name);	});	dir_f = (struct jffs_file *) dir->u.generic_ip;	c = dir_f->c;	result = -ENOENT;	if (!(del_f = jffs_find_child(dir_f, dentry->d_name.name,				      dentry->d_name.len))) {		D(printk("jffs_remove(): jffs_find_child() failed.\n"));		goto jffs_remove_end;	}	if (S_ISDIR(type)) {		struct jffs_file *child = del_f->children;		while(child) {			if( !child->deleted ) {				result = -ENOTEMPTY;				goto jffs_remove_end;			}			child = child->sibling_next;		}	}            	else if (S_ISDIR(del_f->mode)) {		D(printk("jffs_remove(): node is a directory "			 "but it shouldn't be.\n"));		result = -EPERM;		goto jffs_remove_end;	}	inode = dentry->d_inode;	result = -EIO;	if (del_f->ino != inode->i_ino)		goto jffs_remove_end;	if (!inode->i_nlink) {		printk("Deleting nonexistent file inode: %lu, nlink: %d\n",		       inode->i_ino, inode->i_nlink);		inode->i_nlink=1;	}	/* Create a node for the deletion.  */	result = -ENOMEM;	if (!(del_node = jffs_alloc_node())) {		D(printk("jffs_remove(): Allocation failed!\n"));		goto jffs_remove_end;	}	del_node->data_offset = 0;	del_node->removed_size = 0;	/* Initialize the raw inode.  */	raw_inode.magic = JFFS_MAGIC_BITMASK;	raw_inode.ino = del_f->ino;	raw_inode.pino = del_f->pino;/*  	raw_inode.version = del_f->highest_version + 1; */	raw_inode.mode = del_f->mode;	raw_inode.uid = current->fsuid;	raw_inode.gid = current->fsgid;	raw_inode.atime = get_seconds();	raw_inode.mtime = del_f->mtime;	raw_inode.ctime = raw_inode.atime;	raw_inode.offset = 0;	raw_inode.dsize = 0;	raw_inode.rsize = 0;	raw_inode.nsize = 0;	raw_inode.nlink = del_f->nlink;	raw_inode.spare = 0;	raw_inode.rename = 0;	raw_inode.deleted = 1;	/* Write the new node to the flash memory.  */	if (jffs_write_node(c, del_node, &raw_inode, NULL, NULL, 1, del_f) < 0) {		jffs_free_node(del_node);		result = -EIO;		goto jffs_remove_end;	}	/* Update the file.  This operation will make the file disappear	   from the in-memory file system structures.  */	jffs_insert_node(c, del_f, &raw_inode, NULL, del_node);	dir->i_ctime = dir->i_mtime = CURRENT_TIME;	mark_inode_dirty(dir);	inode->i_nlink--;	inode->i_ctime = dir->i_ctime;	mark_inode_dirty(inode);	d_delete(dentry);	/* This also frees the inode */	result = 0;jffs_remove_end:	return result;} /* jffs_remove()  */static intjffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev){	struct jffs_raw_inode raw_inode;	struct jffs_file *dir_f;	struct jffs_node *node = NULL;	struct jffs_control *c;	struct inode *inode;	int result = 0;	u16 data = old_encode_dev(rdev);	int err;	D1(printk("***jffs_mknod()\n"));	if (!old_valid_dev(rdev))		return -EINVAL;	lock_kernel();	dir_f = (struct jffs_file *)dir->u.generic_ip;	c = dir_f->c;	D3(printk (KERN_NOTICE "mknod(): down biglock\n"));	down(&c->fmc->biglock);	/* Create and initialize a new node.  */	if (!(node = jffs_alloc_node())) {		D(printk("jffs_mknod(): Allocation failed!\n"));		result = -ENOMEM;		goto jffs_mknod_err;	}	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 = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;	/*	raw_inode.gid = current->fsgid; */	raw_inode.atime = get_seconds();	raw_inode.mtime = raw_inode.atime;	raw_inode.ctime = raw_inode.atime;	raw_inode.offset = 0;	raw_inode.dsize = 2;	raw_inode.rsize = 0;	raw_inode.nsize = dentry->d_name.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 ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,				   (unsigned char *)&data, 0, NULL)) < 0) {		D(printk("jffs_mknod(): jffs_write_node() failed.\n"));		result = err;		goto jffs_mknod_err;	}	/* Insert the new node into the file system.  */	if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,				    node)) < 0) {		result = err;		goto jffs_mknod_end;	}	inode = jffs_new_inode(dir, &raw_inode, &err);	if (inode == NULL) {		result = err;		goto jffs_mknod_end;	}	init_special_inode(inode, mode, rdev);	d_instantiate(dentry, inode);	goto jffs_mknod_end;jffs_mknod_err:	if (node) {		jffs_free_node(node);	}jffs_mknod_end:	D3(printk (KERN_NOTICE "mknod(): up biglock\n"));	up(&c->fmc->biglock);	unlock_kernel();	return result;} /* jffs_mknod()  */static intjffs_symlink(struct inode *dir, struct dentry *dentry, const char *symname){	struct jffs_raw_inode raw_inode;	struct jffs_control *c;	struct jffs_file *dir_f;	struct jffs_node *node;	struct inode *inode;	int symname_len = strlen(symname);	int err;	lock_kernel();	D1({		int len = dentry->d_name.len; 		char *_name = (char *)kmalloc(len + 1, GFP_KERNEL);		char *_symname = (char *)kmalloc(symname_len + 1, GFP_KERNEL);		memcpy(_name, dentry->d_name.name, len);		_name[len] = '\0';		memcpy(_symname, symname, symname_len);		_symname[symname_len] = '\0';		printk("***jffs_symlink(): dir = 0x%p, "		       "dentry->dname.name = \"%s\", "		       "symname = \"%s\"\n", dir, _name, _symname);		kfree(_name);		kfree(_symname);	});	dir_f = (struct jffs_file *)dir->u.generic_ip;	ASSERT(if (!dir_f) {		printk(KERN_ERR "jffs_symlink(): No reference to a "		       "jffs_file struct in inode.\n");		unlock_kernel();		return -EIO;	});	c = dir_f->c;	/* Create a node and initialize it as much as needed.  */	if (!(node = jffs_alloc_node())) {		D(printk("jffs_symlink(): Allocation failed: node = NULL\n"));		unlock_kernel();		return -ENOMEM;	}	D3(printk (KERN_NOTICE "symlink(): down biglock\n"));	down(&c->fmc->biglock);	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 = S_IFLNK | S_IRWXUGO;	raw_inode.uid = current->fsuid;	raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;	raw_inode.atime = get_seconds();	raw_inode.mtime = raw_inode.atime;	raw_inode.ctime = raw_inode.atime;	raw_inode.offset = 0;	raw_inode.dsize = symname_len;	raw_inode.rsize = 0;	raw_inode.nsize = dentry->d_name.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 ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name,				   (const unsigned char *)symname, 0, NULL)) < 0) {		D(printk("jffs_symlink(): jffs_write_node() failed.\n"));		jffs_free_node(node);		goto jffs_symlink_end;	}	/* Insert the new node into the file system.  */	if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,				    node)) < 0) {		goto jffs_symlink_end;	}	inode = jffs_new_inode(dir, &raw_inode, &err);	if (inode == NULL) {		goto jffs_symlink_end;	}	err = 0;	inode->i_op = &page_symlink_inode_operations;	inode->i_mapping->a_ops = &jffs_address_operations;	d_instantiate(dentry, inode); jffs_symlink_end:	D3(printk (KERN_NOTICE "symlink(): up biglock\n"));	up(&c->fmc->biglock);	unlock_kernel();	return err;} /* jffs_symlink()  *//* Create an inode inside a JFFS directory (dir) and return it. * * By the time this is called, we already have created * the directory cache entry for the new file, but it * is so far negative - it has no inode. * * If the create succeeds, we fill in the inode information * with d_instantiate(). */static intjffs_create(struct inode *dir, struct dentry *dentry, int mode,		struct nameidata *nd){	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;	int err;	lock_kernel();	D1({		int len = dentry->d_name.len;		char *s = (char *)kmalloc(len + 1, GFP_KERNEL);		memcpy(s, dentry->d_name.name, len);		s[len] = '\0';		printk("jffs_create(): dir: 0x%p, name: \"%s\"\n", dir, s);		kfree(s);	});	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");		unlock_kernel();		return -EIO;	});	c = dir_f->c;	/* Create a node and initialize as much as needed.  */	if (!(node = jffs_alloc_node())) {		D(printk("jffs_create(): Allocation failed: node == 0\n"));		unlock_kernel();		return -ENOMEM;	}	D3(printk (KERN_NOTICE "create(): down biglock\n"));	down(&c->fmc->biglock);	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 = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;	raw_inode.atime = get_seconds();	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 = dentry->d_name.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 ((err = jffs_write_node(c, node, &raw_inode,				   dentry->d_name.name, NULL, 0, NULL)) < 0) {		D(printk("jffs_create(): jffs_write_node() failed.\n"));		jffs_free_node(node);		goto jffs_create_end;	}	/* Insert the new node into the file system.  */	if ((err = jffs_insert_node(c, NULL, &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_fop = &jffs_file_operations;	inode->i_mapping->a_ops = &jffs_address_operations;	inode->i_mapping->nrpages = 0;	d_instantiate(dentry, inode); jffs_create_end:	D3(printk (KERN_NOTICE "create(): up biglock\n"));	up(&c->fmc->biglock);	unlock_kernel();	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 dentry *dentry = filp->f_dentry;	struct inode *inode = dentry->d_inode;	int recoverable = 0;	size_t written = 0;	__u32 thiscount = count;	loff_t pos = *ppos;	int err;	inode = filp->f_dentry->d_inode;

⌨️ 快捷键说明

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