Esempio n. 1
0
static int scfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	int ret;
	struct dentry *lower_dentry = scfs_lower_dentry(dentry);

	ret = lower_dentry->d_sb->s_op->statfs(lower_dentry, buf);
	if (ret)
		return ret;

	buf->f_type = SCFS_SUPER_MAGIC;

	return ret;
}
static struct inode *
scfs_do_create(struct inode *parent_inode,
		struct dentry *scfs_dentry, umode_t mode)
{
	struct dentry *lower_file_dentry;
	struct dentry *lower_parent_dentry;
	struct inode *inode;
	int ret;

	SCFS_DEBUG_START;
	
	lower_file_dentry = scfs_lower_dentry(scfs_dentry);
	lower_parent_dentry = lock_parent(lower_file_dentry);

	if (IS_ERR(lower_parent_dentry)) {
		SCFS_PRINT_ERROR("lower_parent_dentry is invalid\n");
		inode = ERR_CAST(lower_parent_dentry);
		goto out;
	}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
	ret = vfs_create(lower_parent_dentry->d_inode, lower_file_dentry,
			mode, true);
#else
	ret = vfs_create(lower_parent_dentry->d_inode, lower_file_dentry,
			mode, NULL);
#endif
	if (ret) {
		SCFS_PRINT_ERROR("error in vfs_create, lower create, ret : %d\n", ret);
		inode = ERR_PTR(ret);
		goto unlock;
	}
	inode = _scfs_get_inode(lower_file_dentry->d_inode, parent_inode->i_sb);
	if (IS_ERR(inode)) {
		SCFS_PRINT_ERROR("error in get_inode, so lower thing will be unlinked\n");
		vfs_unlink(lower_parent_dentry->d_inode, lower_file_dentry);
		goto unlock;
	}
	fsstack_copy_attr_times(parent_inode, lower_parent_dentry->d_inode);
	fsstack_copy_inode_size(parent_inode, lower_parent_dentry->d_inode);

unlock:
	unlock_dir(lower_parent_dentry);
out:
	SCFS_DEBUG_END;
	
	return inode;
}
/*
 * scfs_mkdir
 *
 * Parameters:
 * @*dir: inode of the dir to create
 * @*scfs_dentry: dentry of the dir to create
 * @mode:
 *
 * Return:
 * SCFS_SUCCESS if success, otherwise if error
 *
 * Description:
 * mkdir() for SCFS.
 */
static int scfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
	struct dentry *lower_dir_dentry;
	struct dentry *lower_parent_dentry;
	int ret;

	SCFS_DEBUG_START;
	
	lower_dir_dentry = scfs_lower_dentry(dentry);
	lower_parent_dentry = lock_parent(lower_dir_dentry);
	ret = vfs_mkdir(lower_parent_dentry->d_inode, lower_dir_dentry, mode);
	if (ret || !lower_dir_dentry->d_inode) {
		SCFS_PRINT_ERROR("dir %s vfs_mkdir failed, "
			"lower_dir %s lower_parent %s mode %x\n",
			dentry->d_name.name,
			lower_dir_dentry->d_name.name,
			lower_parent_dentry->d_name.name, mode);
		goto out;
	}
	ret = scfs_interpose(lower_dir_dentry, dentry, dir->i_sb);
	if (ret) {
		SCFS_PRINT_ERROR("dir %s interpose failed, "
			"lower_dir %s lower_parent %s mode %x\n",
			dentry->d_name.name,
			lower_dir_dentry->d_name.name,
			lower_parent_dentry->d_name.name, mode);
		vfs_rmdir(lower_parent_dentry->d_inode, lower_dir_dentry);
		goto out;
	}
	fsstack_copy_attr_times(dir, lower_parent_dentry->d_inode);
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
	set_nlink(dir, lower_parent_dentry->d_inode->i_nlink);

out:
	unlock_dir(lower_parent_dentry);
	if (!dentry->d_inode)
		d_drop(dentry);

	SCFS_DEBUG_END;

	return ret;
}
Esempio n. 4
0
static int scfs_do_unlink(struct inode *dir, struct dentry *dentry, struct inode *inode)
{
	struct dentry *lower_dentry = scfs_lower_dentry(dentry);
	struct inode *lower_dir_inode = scfs_lower_inode(dir);
	struct dentry *lower_dir_dentry;
	int ret;

	dget(lower_dentry);
	lower_dir_dentry = lock_parent(lower_dentry);
	ret = vfs_unlink(lower_dir_inode, lower_dentry);
	if (ret) {
		SCFS_PRINT_ERROR("error in vfs_unlink, ret : %d\n", ret);
		goto out;
	}
	fsstack_copy_attr_times(dir, lower_dir_inode);
	set_nlink(inode, scfs_lower_inode(inode)->i_nlink);
	inode->i_ctime = dir->i_ctime;
	d_drop(dentry);
out:
	unlock_dir(lower_dir_dentry);
	dput(lower_dentry);
	return ret;
}