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; }
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)) return -EINVAL; root_inode = hypfs_make_inode(sb, S_IFDIR | 0755); if (!root_inode) return -ENOMEM; root_inode->i_op = &simple_dir_inode_operations; root_inode->i_fop = &simple_dir_operations; sb->s_root = root_dentry = d_make_root(root_inode); if (!root_dentry) return -ENOMEM; if (MACHINE_IS_VM) rc = hypfs_vm_create_files(sb, root_dentry); else rc = hypfs_diag_create_files(sb, root_dentry); if (rc) return rc; sbi->update_file = hypfs_create_update_file(sb, root_dentry); if (IS_ERR(sbi->update_file)) return PTR_ERR(sbi->update_file); hypfs_update_update(sb); pr_info("Hypervisor filesystem mounted\n"); return 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; }