static struct file *vperfctr_get_filp(void)
{
	struct file *filp;
	struct inode *inode;
	struct dentry *dentry;

	filp = get_empty_filp();
	if (!filp)
		goto out;
	inode = vperfctr_get_inode();
	if (!inode)
		goto out_filp;
	dentry = vperfctr_d_alloc_root(inode);
	if (!dentry)
		goto out_inode;

	filp->f_vfsmnt = mntget(vperfctr_mnt);
	filp->f_dentry = dentry;
	filp->f_mapping = dentry->d_inode->i_mapping;

	filp->f_pos = 0;
	filp->f_flags = 0;
	filp->f_op = &vperfctr_file_ops; /* fops_get() if MODULE */
	filp->f_mode = FMODE_READ;
	filp->f_version = 0;

	return filp;

 out_inode:
	iput(inode);
 out_filp:
	put_filp(filp);	/* doesn't run ->release() like fput() does */
 out:
	return NULL;
}
Beispiel #2
0
static struct file *vperfctr_get_filp(void)
{
	struct file *filp;
	struct inode *inode;
	struct dentry *dentry;

	inode = vperfctr_get_inode();
	if (!inode)
		goto out;
	dentry = vperfctr_d_alloc_root(inode);
	if (!dentry)
		goto out_inode;
	/*
	 * Create the filp _after_ the inode and dentry, to avoid
	 * needing access to put_filp(), which is no longer exported
	 * starting with kernel 2.6.10-rc1. fput() is available but
	 * doesn't work on incomplete files. We now need access to
	 * dput() instead, but that's Ok.
	 */
	filp = get_empty_filp();
	if (!filp)
		goto out_dentry;

	filp_vfsmnt(filp) = mntget(vperfctr_mnt);
	filp_dentry(filp) = dentry;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,2)
	filp->f_mapping = dentry->d_inode->i_mapping;
#endif

	filp->f_pos = 0;
	filp->f_flags = 0;
	filp->f_op = fops_get(&vperfctr_file_ops); /* fops_get() for MODULE */
	filp->f_mode = FMODE_READ;
	filp->f_version = 0;

	return filp;

 out_dentry:
	dput(dentry);
	goto out; /* dput() also does iput() */
 out_inode:
	iput(inode);
 out:
	return NULL;
}