diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/fs/open.c b/fs/open.c index d98e19239bb7..0285ce7dbd51 100644 --- a/fs/open.c +++ b/fs/open.c @@ -68,7 +68,6 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, long vfs_truncate(const struct path *path, loff_t length) { struct inode *inode; - struct dentry *upperdentry; long error; inode = path->dentry->d_inode; @@ -91,17 +90,7 @@ long vfs_truncate(const struct path *path, loff_t length) if (IS_APPEND(inode)) goto mnt_drop_write_and_out; - /* - * If this is an overlayfs then do as if opening the file so we get - * write access on the upper inode, not on the overlay inode. For - * non-overlay filesystems d_real() is an identity function. - */ - upperdentry = d_real(path->dentry, NULL, O_WRONLY, 0); - error = PTR_ERR(upperdentry); - if (IS_ERR(upperdentry)) - goto mnt_drop_write_and_out; - - error = get_write_access(upperdentry->d_inode); + error = get_write_access(inode); if (error) goto mnt_drop_write_and_out; @@ -120,7 +109,7 @@ long vfs_truncate(const struct path *path, loff_t length) error = do_truncate(path->dentry, length, 0, NULL); put_write_and_out: - put_write_access(upperdentry->d_inode); + put_write_access(inode); mnt_drop_write_and_out: mnt_drop_write(path->mnt); out: @@ -707,12 +696,12 @@ int ksys_fchown(unsigned int fd, uid_t user, gid_t group) if (!f.file) goto out; - error = mnt_want_write_file_path(f.file); + error = mnt_want_write_file(f.file); if (error) goto out_fput; audit_file(f.file); error = chown_common(&f.file->f_path, user, group); - mnt_drop_write_file_path(f.file); + mnt_drop_write_file(f.file); out_fput: fdput(f); out: @@ -887,13 +876,8 @@ EXPORT_SYMBOL(file_path); */ int vfs_open(const struct path *path, struct file *file) { - struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags, 0); - - if (IS_ERR(dentry)) - return PTR_ERR(dentry); - file->f_path = *path; - return do_dentry_open(file, d_backing_inode(dentry), NULL); + return do_dentry_open(file, d_backing_inode(path->dentry), NULL); } struct file *dentry_open(const struct path *path, int flags, @@ -919,6 +903,24 @@ struct file *dentry_open(const struct path *path, int flags, } EXPORT_SYMBOL(dentry_open); +struct file *open_with_fake_path(const struct path *path, int flags, + struct inode *inode, const struct cred *cred) +{ + struct file *f = alloc_empty_file_noaccount(flags, cred); + if (!IS_ERR(f)) { + int error; + + f->f_path = *path; + error = do_dentry_open(f, inode, NULL); + if (error) { + fput(f); + f = ERR_PTR(error); + } + } + return f; +} +EXPORT_SYMBOL(open_with_fake_path); + static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op) { int lookup_flags = 0; |