diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/fs/open.c b/fs/open.c index 93ae3cdee4ab..4fd6e256f4f4 100644 --- a/fs/open.c +++ b/fs/open.c @@ -840,13 +840,13 @@ EXPORT_SYMBOL(file_path); int vfs_open(const struct path *path, struct file *file, const struct cred *cred) { - struct inode *inode = vfs_select_inode(path->dentry, file->f_flags); + struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags); - if (IS_ERR(inode)) - return PTR_ERR(inode); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); file->f_path = *path; - return do_dentry_open(file, inode, NULL, cred); + return do_dentry_open(file, d_backing_inode(dentry), NULL, cred); } struct file *dentry_open(const struct path *path, int flags, @@ -998,6 +998,26 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, } EXPORT_SYMBOL(file_open_root); +struct file *filp_clone_open(struct file *oldfile) +{ + struct file *file; + int retval; + + file = get_empty_filp(); + if (IS_ERR(file)) + return file; + + file->f_flags = oldfile->f_flags; + retval = vfs_open(&oldfile->f_path, file, oldfile->f_cred); + if (retval) { + put_filp(file); + return ERR_PTR(retval); + } + + return file; +} +EXPORT_SYMBOL(filp_clone_open); + long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; |