/* Reopen the same filesystem object as an exsiting filp. * Result is a distinct filp, with potentially different f_flags and f_mode. */ struct file * cr_filp_reopen(const struct file *orig_filp, int new_flags) { return orig_filp ? cr_dentry_open(dget(orig_filp->f_dentry), mntget(orig_filp->f_vfsmnt), new_flags) : ERR_PTR(-EBADF); }
/* Call both cr_permision() and cr_dentry_open(). */ struct file * cr_dentry_open_perm(struct path *path, int flags) { struct file *filp; int acc_mask = ("\004\002\006\006"[flags&O_ACCMODE]); /* ACC_MODE(open_to_namei_flags()) */ int err; err = cr_permission(path->dentry->d_inode, acc_mask); filp = ERR_PTR(err); if (!IS_ERR(filp)) { filp = cr_dentry_open(path, flags); } 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 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; }