Ejemplo n.º 1
0
static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct inode *root_inode;
	struct dentry *root_dentry;
	int rc = 0;
	struct hypfs_sb_info *sbi;

	sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;
	mutex_init(&sbi->lock);
	sbi->uid = current->uid;
	sbi->gid = current->gid;
	sb->s_fs_info = sbi;
	sb->s_blocksize = PAGE_CACHE_SIZE;
	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
	sb->s_magic = HYPFS_MAGIC;
	sb->s_op = &hypfs_s_ops;
	if (hypfs_parse_options(data, sb)) {
		rc = -EINVAL;
		goto err_alloc;
	}
	root_inode = hypfs_make_inode(sb, S_IFDIR | 0755);
	if (!root_inode) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	root_inode->i_op = &simple_dir_inode_operations;
	root_inode->i_fop = &simple_dir_operations;
	root_dentry = d_alloc_root(root_inode);
	if (!root_dentry) {
		iput(root_inode);
		rc = -ENOMEM;
		goto err_alloc;
	}
	if (MACHINE_IS_VM)
		rc = hypfs_vm_create_files(sb, root_dentry);
	else
		rc = hypfs_diag_create_files(sb, root_dentry);
	if (rc)
		goto err_tree;
	sbi->update_file = hypfs_create_update_file(sb, root_dentry);
	if (IS_ERR(sbi->update_file)) {
		rc = PTR_ERR(sbi->update_file);
		goto err_tree;
	}
	hypfs_update_update(sb);
	sb->s_root = root_dentry;
	printk(KERN_INFO "hypfs: Hypervisor filesystem mounted\n");
	return 0;

err_tree:
	hypfs_delete_tree(root_dentry);
	d_genocide(root_dentry);
	dput(root_dentry);
err_alloc:
	kfree(sbi);
	return rc;
}
Ejemplo n.º 2
0
static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov,
			      unsigned long nr_segs, loff_t offset)
{
	int rc;
	struct super_block *sb;
	struct hypfs_sb_info *fs_info;
	size_t count = iov_length(iov, nr_segs);

	sb = iocb->ki_filp->f_path.dentry->d_inode->i_sb;
	fs_info = sb->s_fs_info;
	/*
	 * Currently we only allow one update per second for two reasons:
	 * 1. diag 204 is VERY expensive
	 * 2. If several processes do updates in parallel and then read the
	 *    hypfs data, the likelihood of collisions is reduced, if we restrict
	 *    the minimum update interval. A collision occurs, if during the
	 *    data gathering of one process another process triggers an update
	 *    If the first process wants to ensure consistent data, it has
	 *    to restart data collection in this case.
	 */
	mutex_lock(&fs_info->lock);
	if (fs_info->last_update == get_seconds()) {
		rc = -EBUSY;
		goto out;
	}
	hypfs_delete_tree(sb->s_root);
	if (MACHINE_IS_VM)
		rc = hypfs_vm_create_files(sb, sb->s_root);
	else
		rc = hypfs_diag_create_files(sb, sb->s_root);
	if (rc) {
		pr_err("Updating the hypfs tree failed\n");
		hypfs_delete_tree(sb->s_root);
		goto out;
	}
	hypfs_update_update(sb);
	rc = count;
out:
	mutex_unlock(&fs_info->lock);
	return rc;
}
Ejemplo n.º 3
0
static void hypfs_kill_super(struct super_block *sb)
{
	struct hypfs_sb_info *sb_info = sb->s_fs_info;

	if (sb->s_root)
		hypfs_delete_tree(sb->s_root);
	if (sb_info->update_file)
		hypfs_remove(sb_info->update_file);
	kfree(sb->s_fs_info);
	sb->s_fs_info = NULL;
	kill_litter_super(sb);
}