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; }
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; }