/* Calls cr_mknod and then opens with the given flags, returning a (struct file *) */ struct file * cr_filp_mknod(cr_errbuf_t *eb, const char *name, int mode, int flags, unsigned long unlinked_id) { struct nameidata nd; struct dentry * dentry; struct file *filp; /* mknod */ dentry = cr_mknod(eb, &nd, name, mode, unlinked_id); if (IS_ERR(dentry)) { CR_KTRACE_UNEXPECTED("Failed to recreate %sfilesystem object %s, err=%d.", unlinked_id?"unlinked ":"", name, (int)PTR_ERR(dentry)); filp = (struct file *)dentry; goto out; } /* now open it */ filp = cr_dentry_open(dget(dentry), mntget(nd.nd_mnt), flags); if (IS_ERR(filp)) { CR_ERR_EB(eb, "Failed to reopen %sfilesystem object %s, err=%d.", unlinked_id?"unlinked ":"", name, (int)PTR_ERR(dentry)); goto out_dput; } /* check that we actually got the expected type */ if ((mode ^ filp->f_dentry->d_inode->i_mode) & S_IFMT) { CR_ERR_EB(eb, "Type conflict when recreating %sfilesystem object %s.", unlinked_id?"unlinked ":"", name); fput(filp); filp = ERR_PTR(-EEXIST); goto out_dput; } out_dput: dput(dentry); cr_path_release(&nd); out: return filp; }
/* Calls cr_mknod and then opens with the given flags, returning a (struct file *) */ struct file * cr_filp_mknod(cr_errbuf_t *eb, const char *name, int mode, int flags, unsigned long unlinked_id) { struct path path; struct file *filp; int err; /* mknod */ err = cr_mknod(eb, &path, name, mode, unlinked_id); if (err) { CR_KTRACE_UNEXPECTED("Failed to recreate %sfilesystem object %s, err=%d.", unlinked_id?"unlinked ":"", name, err); filp = (struct file *)ERR_PTR(err); goto out; } /* now open it */ path_get(&path); filp = cr_dentry_open_perm(&path, flags); if (IS_ERR(filp)) { CR_ERR_EB(eb, "Failed to reopen %sfilesystem object %s, err=%d.", unlinked_id?"unlinked ":"", name, (int)PTR_ERR(filp)); goto out_put; } /* check that we actually got the expected type */ if ((mode ^ filp->f_dentry->d_inode->i_mode) & S_IFMT) { CR_ERR_EB(eb, "Type conflict when recreating %sfilesystem object %s.", unlinked_id?"unlinked ":"", name); fput(filp); filp = ERR_PTR(-EEXIST); } out_put: path_put(&path); out: return filp; }