Exemple #1
0
static void scfs_destroy_inode(struct inode *inode)
{
	struct scfs_sb_info *sbi = SCFS_S(inode->i_sb);
	struct scfs_inode_info *sii = SCFS_I(inode);

	if (sii->cinfo_array)
		scfs_cinfo_free(sii, sii->cinfo_array);

	if (!list_empty(&sii->cinfo_list)) {
		SCFS_PRINT_ERROR("cinfo list is not empty!\n");
		ASSERT(0);
	}

	if (sii->cluster_buffer.c_page) {
		__free_pages(sii->cluster_buffer.c_page, SCFS_MEMPOOL_ORDER + 1);
		sii->cluster_buffer.c_buffer = NULL;
		sii->cluster_buffer.c_page = NULL;
	} 

	if (sii->cluster_buffer.u_page) {
		__free_pages(sii->cluster_buffer.u_page, SCFS_MEMPOOL_ORDER + 1);
		sii->cluster_buffer.u_buffer = NULL;
		sii->cluster_buffer.u_page = NULL;
		atomic_sub(1, &sbi->current_file_count);
	}

	kmem_cache_free(scfs_inode_info_cache, sii);
	profile_sub_kmcached(sizeof(struct scfs_inode_info), SCFS_S(inode->i_sb));
}
/*
 * scfs_file_release
 */
static int scfs_file_release(struct inode *inode, struct file *file)
{
	int ret;

	SCFS_PRINT("f:%s calling fput with lower_file\n",
			file->f_path.dentry->d_name.name);

	if (file->f_flags & (O_RDWR | O_WRONLY)) {
		CLEAR_WROPENED(SCFS_I(inode));
		ret = scfs_write_meta(file);
		if (ret)
			return ret;
	}

	fput(SCFS_F(file)->lower_file);
	kmem_cache_free(scfs_file_info_cache, SCFS_F(file));
	profile_sub_kmcached(sizeof(struct scfs_file_info), SCFS_S(inode->i_sb));

	return 0;
}
static int scfs_open(struct inode *inode, struct file *file)
{
	struct scfs_sb_info *sbi = SCFS_S(inode->i_sb);
	struct scfs_inode_info *sii = SCFS_I(inode);
	struct scfs_file_info *fi;
	int ret = 0;
	struct file *lower_file;

	if (IS_WROPENED(sii)) {
		SCFS_PRINT("This file is already opened with 'WRITE' flag\n");
		return -EPERM;
	}

	fi = kmem_cache_zalloc(scfs_file_info_cache, GFP_KERNEL);
	if (!fi)
		return -ENOMEM;

	profile_add_kmcached(sizeof(struct scfs_file_info), sbi);

	file->private_data = fi;

	mutex_lock(&sii->cinfo_mutex);
	if (IS_INVALID_META(sii)) {
		SCFS_PRINT("meta is invalid, so we should re-load it\n");
		ret = scfs_reload_meta(file);
		if (ret) {
			SCFS_PRINT_ERROR("error in re-reading footer, err : %d\n", ret);
			goto out;
		}
	} else if (sii->compressed && !sii->cinfo_array) {
		/* 1st lower-open is for getting cinfo */
		ret = scfs_initialize_lower_file(file->f_dentry, &lower_file, O_RDONLY); 
		if (ret) {
			SCFS_PRINT_ERROR("err in get_lower_file %s\n",
				file->f_dentry->d_name.name);
			goto out;
		}
		scfs_set_lower_file(file, lower_file);

		SCFS_PRINT("info size = %d \n", sii->cinfo_array_size);
		ret = scfs_load_cinfo(sii, lower_file);
		if (ret) {
			SCFS_PRINT_ERROR("err in loading cinfo, ret : %d\n",
				file->f_dentry->d_name.name);
			fput(lower_file);
			goto out;
		}
		fput(lower_file);
	}

	ret = scfs_initialize_lower_file(file->f_dentry, &lower_file, file->f_flags); 
	if (ret) {
		SCFS_PRINT_ERROR("err in get_lower_file %s\n",
			file->f_dentry->d_name.name);

		goto out;
	}
	scfs_set_lower_file(file, lower_file);
out:
	if (!ret) {
		fsstack_copy_attr_all(inode, scfs_lower_inode(inode));
		if (file->f_flags & (O_RDWR | O_WRONLY))
			MAKE_WROPENED(sii);
	} else {
		scfs_set_lower_file(file, NULL);
		kmem_cache_free(scfs_file_info_cache, file->private_data);
		profile_sub_kmcached(sizeof(struct scfs_file_info), sbi);
		sii->cinfo_array = NULL;
	}
	mutex_unlock(&sii->cinfo_mutex);
	SCFS_PRINT("lower, dentry name : %s, count : %d, ret : %d\n",
		file->f_dentry->d_name.name, file->f_dentry->d_count, ret);
	
	return ret;
}