Lines Matching +full:real +full:-
1 // SPDX-License-Identifier: GPL-2.0-only
14 #include <linux/backing-file.h>
30 struct inode *realinode = d_inode(realpath->dentry); in ovl_open_realfile()
35 int flags = file->f_flags | OVL_OPEN_FLAGS; in ovl_open_realfile()
42 old_cred = ovl_override_creds(inode->i_sb); in ovl_open_realfile()
43 real_idmap = mnt_idmap(realpath->mnt); in ovl_open_realfile()
51 realfile = backing_file_open(&file->f_path, flags, realpath, in ovl_open_realfile()
56 pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n", in ovl_open_realfile()
57 file, file, ovl_whatisit(inode, realinode), file->f_flags, in ovl_open_realfile()
58 realfile, IS_ERR(realfile) ? 0 : realfile->f_flags); in ovl_open_realfile()
72 if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode)) in ovl_change_flags()
73 return -EPERM; in ovl_change_flags()
75 if ((flags & O_DIRECT) && !(file->f_mode & FMODE_CAN_ODIRECT)) in ovl_change_flags()
76 return -EINVAL; in ovl_change_flags()
78 if (file->f_op->check_flags) { in ovl_change_flags()
79 err = file->f_op->check_flags(flags); in ovl_change_flags()
84 spin_lock(&file->f_lock); in ovl_change_flags()
85 file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags; in ovl_change_flags()
86 file->f_iocb_flags = iocb_flags(file); in ovl_change_flags()
87 spin_unlock(&file->f_lock); in ovl_change_flags()
92 static int ovl_real_fdget_meta(const struct file *file, struct fd *real, in ovl_real_fdget_meta() argument
96 struct file *realfile = file->private_data; in ovl_real_fdget_meta()
100 real->word = (unsigned long)realfile; in ovl_real_fdget_meta()
113 return -EIO; in ovl_real_fdget_meta()
120 real->word = (unsigned long)f | FDPUT_FPUT; in ovl_real_fdget_meta()
125 if (unlikely((file->f_flags ^ realfile->f_flags) & ~OVL_OPEN_FLAGS)) in ovl_real_fdget_meta()
126 return ovl_change_flags(realfile, file->f_flags); in ovl_real_fdget_meta()
131 static int ovl_real_fdget(const struct file *file, struct fd *real) in ovl_real_fdget() argument
137 real->word = (unsigned long)f; in ovl_real_fdget()
141 return ovl_real_fdget_meta(file, real, false); in ovl_real_fdget()
156 err = ovl_maybe_copy_up(dentry, file->f_flags); in ovl_open()
161 file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); in ovl_open()
165 return -EIO; in ovl_open()
171 file->private_data = realfile; in ovl_open()
178 fput(file->private_data); in ovl_release()
186 struct fd real; in ovl_llseek() local
191 * The two special cases below do not need to involve real fs, in ovl_llseek()
196 return file->f_pos; in ovl_llseek()
202 ret = ovl_real_fdget(file, &real); in ovl_llseek()
208 * through copy up and modified on read/write, but only real in ovl_llseek()
209 * fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose in ovl_llseek()
210 * limitations that are more strict than ->s_maxbytes for specific in ovl_llseek()
211 * files, so we use the real file to perform seeks. in ovl_llseek()
214 fd_file(real)->f_pos = file->f_pos; in ovl_llseek()
216 old_cred = ovl_override_creds(inode->i_sb); in ovl_llseek()
217 ret = vfs_llseek(fd_file(real), offset, whence); in ovl_llseek()
220 file->f_pos = fd_file(real)->f_pos; in ovl_llseek()
223 fdput(real); in ovl_llseek()
245 if (file->f_flags & O_NOATIME) in ovl_file_accessed()
264 touch_atime(&file->f_path); in ovl_file_accessed()
269 struct file *file = iocb->ki_filp; in ovl_read_iter()
270 struct fd real; in ovl_read_iter() local
273 .cred = ovl_creds(file_inode(file)->i_sb), in ovl_read_iter()
281 ret = ovl_real_fdget(file, &real); in ovl_read_iter()
285 ret = backing_file_read_iter(fd_file(real), iter, iocb, iocb->ki_flags, in ovl_read_iter()
287 fdput(real); in ovl_read_iter()
294 struct file *file = iocb->ki_filp; in ovl_write_iter()
296 struct fd real; in ovl_write_iter() local
298 int ifl = iocb->ki_flags; in ovl_write_iter()
300 .cred = ovl_creds(inode->i_sb), in ovl_write_iter()
312 ret = ovl_real_fdget(file, &real); in ovl_write_iter()
316 if (!ovl_should_sync(OVL_FS(inode->i_sb))) in ovl_write_iter()
324 ret = backing_file_write_iter(fd_file(real), iter, iocb, ifl, &ctx); in ovl_write_iter()
325 fdput(real); in ovl_write_iter()
337 struct fd real; in ovl_splice_read() local
340 .cred = ovl_creds(file_inode(in)->i_sb), in ovl_splice_read()
345 ret = ovl_real_fdget(in, &real); in ovl_splice_read()
349 ret = backing_file_splice_read(fd_file(real), ppos, pipe, len, flags, &ctx); in ovl_splice_read()
350 fdput(real); in ovl_splice_read()
357 * due to lock order inversion between pipe->mutex in iter_file_splice_write()
358 * and file_start_write(fd_file(real)) in ovl_write_iter().
361 * the real file.
366 struct fd real; in ovl_splice_write() local
370 .cred = ovl_creds(inode->i_sb), in ovl_splice_write()
379 ret = ovl_real_fdget(out, &real); in ovl_splice_write()
383 ret = backing_file_splice_write(pipe, fd_file(real), ppos, len, flags, &ctx); in ovl_splice_write()
384 fdput(real); in ovl_splice_write()
394 struct fd real; in ovl_fsync() local
398 ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb)); in ovl_fsync()
402 ret = ovl_real_fdget_meta(file, &real, !datasync); in ovl_fsync()
407 if (file_inode(fd_file(real)) == ovl_inode_upper(file_inode(file))) { in ovl_fsync()
408 old_cred = ovl_override_creds(file_inode(file)->i_sb); in ovl_fsync()
409 ret = vfs_fsync_range(fd_file(real), start, end, datasync); in ovl_fsync()
413 fdput(real); in ovl_fsync()
420 struct file *realfile = file->private_data; in ovl_mmap()
422 .cred = ovl_creds(file_inode(file)->i_sb), in ovl_mmap()
433 struct fd real; in ovl_fallocate() local
444 ret = ovl_real_fdget(file, &real); in ovl_fallocate()
448 old_cred = ovl_override_creds(file_inode(file)->i_sb); in ovl_fallocate()
449 ret = vfs_fallocate(fd_file(real), mode, offset, len); in ovl_fallocate()
455 fdput(real); in ovl_fallocate()
465 struct fd real; in ovl_fadvise() local
469 ret = ovl_real_fdget(file, &real); in ovl_fadvise()
473 old_cred = ovl_override_creds(file_inode(file)->i_sb); in ovl_fadvise()
474 ret = vfs_fadvise(fd_file(real), offset, len, advice); in ovl_fadvise()
477 fdput(real); in ovl_fadvise()
516 old_cred = ovl_override_creds(file_inode(file_out)->i_sb); in ovl_copyfile()
563 return -EINVAL; in ovl_remap_file_range()
577 return -EPERM; in ovl_remap_file_range()
585 struct fd real; in ovl_flush() local
589 err = ovl_real_fdget(file, &real); in ovl_flush()
593 if (fd_file(real)->f_op->flush) { in ovl_flush()
594 old_cred = ovl_override_creds(file_inode(file)->i_sb); in ovl_flush()
595 err = fd_file(real)->f_op->flush(fd_file(real), id); in ovl_flush()
598 fdput(real); in ovl_flush()