static int scfs_inode_test(struct inode *inode, void *lower_inode)
{
	if (scfs_lower_inode(inode) == (struct inode *)lower_inode)
		return 1;

	return 0;
}
Esempio n. 2
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;
}
Esempio n. 3
0
static void scfs_evict_inode(struct inode *inode)
{
	struct inode *lower_inode;
	struct scfs_inode_info *sii = SCFS_I(inode);

	truncate_inode_pages(&inode->i_data, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
	clear_inode(inode);
#else
	end_writeback(inode);
#endif
	/* to conserve memory, evicted inode will throw out the cluster info */
	if (sii->cinfo_array) {
		scfs_cinfo_free(sii, sii->cinfo_array);
		sii->cinfo_array = NULL;
	}
	if (!list_empty(&sii->cinfo_list))
		SCFS_PRINT_ERROR("cinfo list is not empty!\n");

	lower_inode = scfs_lower_inode(inode);
	scfs_set_lower_inode(inode, NULL);
	iput(lower_inode);
}
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;
}