^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/cred.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/splice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "overlayfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define OVL_IOCB_MASK (IOCB_DSYNC | IOCB_HIPRI | IOCB_NOWAIT | IOCB_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct ovl_aio_req {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct kiocb iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) refcount_t ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct kiocb *orig_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct fd fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static struct kmem_cache *ovl_aio_request_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static char ovl_whatisit(struct inode *inode, struct inode *realinode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (realinode != ovl_inode_upper(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return 'l';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (ovl_has_upperdata(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return 'u';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return 'm';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* No atime modificaton nor notify on underlying */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static struct file *ovl_open_realfile(const struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct inode *realinode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct file *realfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int flags = file->f_flags | OVL_OPEN_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int acc_mode = ACC_MODE(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (flags & O_APPEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) acc_mode |= MAY_APPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) old_cred = ovl_override_creds(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) err = inode_permission(realinode, MAY_OPEN | acc_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) realfile = ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) } else if (old_cred && !inode_owner_or_capable(realinode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) realfile = ERR_PTR(-EPERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) realfile = open_with_fake_path(&file->f_path, flags, realinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ovl_revert_creds(inode->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) file, file, ovl_whatisit(inode, realinode), file->f_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) realfile, IS_ERR(realfile) ? 0 : realfile->f_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return realfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define OVL_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int ovl_change_flags(struct file *file, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) flags |= OVL_OPEN_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* If some flag changed that cannot be changed then something's amiss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) flags &= OVL_SETFL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (flags & O_DIRECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (!file->f_mapping->a_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) !file->f_mapping->a_ops->direct_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (file->f_op->check_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) err = file->f_op->check_flags(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) spin_lock(&file->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) spin_unlock(&file->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bool allow_meta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct inode *realinode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) real->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) real->file = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (allow_meta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) realinode = ovl_inode_real(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) realinode = ovl_inode_realdata(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Has it been copied up since we'd opened it? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (unlikely(file_inode(real->file) != realinode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) real->flags = FDPUT_FPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) real->file = ovl_open_realfile(file, realinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return PTR_ERR_OR_ZERO(real->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Did the flags change since open? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (unlikely((file->f_flags ^ real->file->f_flags) & ~OVL_OPEN_FLAGS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return ovl_change_flags(real->file, file->f_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int ovl_real_fdget(const struct file *file, struct fd *real)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (d_is_dir(file_dentry(file))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) real->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) real->file = ovl_dir_real_file(file, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return PTR_ERR_OR_ZERO(real->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return ovl_real_fdget_meta(file, real, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static int ovl_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct file *realfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) err = ovl_maybe_copy_up(file_dentry(file), file->f_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* No longer need these flags, so don't pass them on to underlying fs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) realfile = ovl_open_realfile(file, ovl_inode_realdata(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (IS_ERR(realfile))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return PTR_ERR(realfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) file->private_data = realfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int ovl_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) fput(file->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) loff_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * The two special cases below do not need to involve real fs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * so we can optimizing concurrent callers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (whence == SEEK_CUR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (whence == SEEK_SET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return vfs_setpos(file, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = ovl_real_fdget(file, &real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Overlay file f_pos is the master copy that is preserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * through copy up and modified on read/write, but only real
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * limitations that are more strict than ->s_maxbytes for specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * files, so we use the real file to perform seeks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ovl_inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) real.file->f_pos = file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) old_cred = ovl_override_creds(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = vfs_llseek(real.file, offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ovl_revert_creds(inode->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) file->f_pos = real.file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ovl_inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void ovl_file_accessed(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct inode *inode, *upperinode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (file->f_flags & O_NOATIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) upperinode = ovl_inode_upper(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!upperinode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) !timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) inode->i_mtime = upperinode->i_mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) inode->i_ctime = upperinode->i_ctime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) touch_atime(&file->f_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static inline void ovl_aio_put(struct ovl_aio_req *aio_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (refcount_dec_and_test(&aio_req->ref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) fdput(aio_req->fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) kmem_cache_free(ovl_aio_request_cachep, aio_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct kiocb *iocb = &aio_req->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct kiocb *orig_iocb = aio_req->orig_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (iocb->ki_flags & IOCB_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct inode *inode = file_inode(orig_iocb->ki_filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Actually acquired in ovl_write_iter() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) __sb_writers_acquired(file_inode(iocb->ki_filp)->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) SB_FREEZE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) file_end_write(iocb->ki_filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ovl_copyattr(ovl_inode_real(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) orig_iocb->ki_pos = iocb->ki_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ovl_aio_put(aio_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static void ovl_aio_rw_complete(struct kiocb *iocb, long res, long res2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct ovl_aio_req *aio_req = container_of(iocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct ovl_aio_req, iocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct kiocb *orig_iocb = aio_req->orig_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ovl_aio_cleanup_handler(aio_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) orig_iocb->ki_complete(orig_iocb, res, res2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct file *file = iocb->ki_filp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (!iov_iter_count(iter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ret = ovl_real_fdget(file, &real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (iocb->ki_flags & IOCB_DIRECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) (!real.file->f_mapping->a_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) !real.file->f_mapping->a_ops->direct_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto out_fdput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) old_cred = ovl_override_creds(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (is_sync_kiocb(iocb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) iocb_to_rw_flags(iocb->ki_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) OVL_IOCB_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct ovl_aio_req *aio_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) aio_req = kmem_cache_zalloc(ovl_aio_request_cachep, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!aio_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) aio_req->fd = real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) real.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) aio_req->orig_iocb = iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) kiocb_clone(&aio_req->iocb, iocb, real.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) aio_req->iocb.ki_complete = ovl_aio_rw_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) refcount_set(&aio_req->ref, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ovl_aio_put(aio_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (ret != -EIOCBQUEUED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ovl_aio_cleanup_handler(aio_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ovl_revert_creds(file_inode(file)->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ovl_file_accessed(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) out_fdput:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct file *file = iocb->ki_filp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int ifl = iocb->ki_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!iov_iter_count(iter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* Update mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ovl_copyattr(ovl_inode_real(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret = file_remove_privs(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = ovl_real_fdget(file, &real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (iocb->ki_flags & IOCB_DIRECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) (!real.file->f_mapping->a_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) !real.file->f_mapping->a_ops->direct_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) goto out_fdput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!ovl_should_sync(OVL_FS(inode->i_sb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ifl &= ~(IOCB_DSYNC | IOCB_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) old_cred = ovl_override_creds(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (is_sync_kiocb(iocb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) file_start_write(real.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) iocb_to_rw_flags(ifl, OVL_IOCB_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) file_end_write(real.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Update size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ovl_copyattr(ovl_inode_real(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct ovl_aio_req *aio_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) aio_req = kmem_cache_zalloc(ovl_aio_request_cachep, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!aio_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) file_start_write(real.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* Pacify lockdep, same trick as done in aio_write() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) __sb_writers_release(file_inode(real.file)->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) SB_FREEZE_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) aio_req->fd = real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) real.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) aio_req->orig_iocb = iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) kiocb_clone(&aio_req->iocb, iocb, real.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) aio_req->iocb.ki_flags = ifl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) aio_req->iocb.ki_complete = ovl_aio_rw_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) refcount_set(&aio_req->ref, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ret = vfs_iocb_iter_write(real.file, &aio_req->iocb, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ovl_aio_put(aio_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (ret != -EIOCBQUEUED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ovl_aio_cleanup_handler(aio_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ovl_revert_creds(file_inode(file)->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) out_fdput:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * Calling iter_file_splice_write() directly from overlay's f_op may deadlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * due to lock order inversion between pipe->mutex in iter_file_splice_write()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * and file_start_write(real.file) in ovl_write_iter().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * So do everything ovl_write_iter() does and call iter_file_splice_write() on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * the real file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) loff_t *ppos, size_t len, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct inode *inode = file_inode(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct inode *realinode = ovl_inode_real(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* Update mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ovl_copyattr(realinode, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ret = file_remove_privs(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ret = ovl_real_fdget(out, &real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) old_cred = ovl_override_creds(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) file_start_write(real.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = iter_file_splice_write(pipe, real.file, ppos, len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) file_end_write(real.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* Update size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ovl_copyattr(realinode, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ovl_revert_creds(inode->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = ovl_real_fdget_meta(file, &real, !datasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Don't sync lower file for fear of receiving EROFS error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) old_cred = ovl_override_creds(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = vfs_fsync_range(real.file, start, end, datasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ovl_revert_creds(file_inode(file)->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct file *realfile = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (!realfile->f_op->mmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (WARN_ON(file != vma->vm_file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) vma->vm_file = get_file(realfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) old_cred = ovl_override_creds(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = call_mmap(vma->vm_file, vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ovl_revert_creds(file_inode(file)->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* Drop reference count from new vm_file value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) fput(realfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Drop reference count from previous vm_file value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) fput(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ovl_file_accessed(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ret = ovl_real_fdget(file, &real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) old_cred = ovl_override_creds(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ret = vfs_fallocate(real.file, mode, offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ovl_revert_creds(file_inode(file)->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* Update size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ovl_copyattr(ovl_inode_real(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret = ovl_real_fdget(file, &real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) old_cred = ovl_override_creds(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = vfs_fadvise(real.file, offset, len, advice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ovl_revert_creds(file_inode(file)->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static long ovl_real_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct fd real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ret = ovl_real_fdget(file, &real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ret = security_file_ioctl(real.file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * Don't override creds, since we currently can't safely check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * permissions before doing so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ret = vfs_ioctl(real.file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) fdput(real);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static long ovl_ioctl_set_flags(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!inode_owner_or_capable(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ret = mnt_want_write_file(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * Prevent copy up if immutable and has no CAP_LINUX_IMMUTABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * capability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!ovl_has_upperdata(inode) && IS_IMMUTABLE(inode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) !capable(CAP_LINUX_IMMUTABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ret = ovl_maybe_copy_up(file_dentry(file), O_WRONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = ovl_real_ioctl(file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) ovl_copyflags(ovl_inode_real(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) mnt_drop_write_file(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) case FS_IOC_GETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case FS_IOC_FSGETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ret = ovl_real_ioctl(file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case FS_IOC_FSSETXATTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case FS_IOC_SETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ret = ovl_ioctl_set_flags(file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ret = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) long ovl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) case FS_IOC32_GETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) cmd = FS_IOC_GETFLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case FS_IOC32_SETFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) cmd = FS_IOC_SETFLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return ovl_ioctl(file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) enum ovl_copyop {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) OVL_COPY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) OVL_CLONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) OVL_DEDUPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct file *file_out, loff_t pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) loff_t len, unsigned int flags, enum ovl_copyop op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct inode *inode_out = file_inode(file_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct fd real_in, real_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) loff_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ret = ovl_real_fdget(file_out, &real_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) ret = ovl_real_fdget(file_in, &real_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) fdput(real_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) case OVL_COPY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ret = vfs_copy_file_range(real_in.file, pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) real_out.file, pos_out, len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case OVL_CLONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ret = vfs_clone_file_range(real_in.file, pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) real_out.file, pos_out, len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case OVL_DEDUPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = vfs_dedupe_file_range_one(real_in.file, pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) real_out.file, pos_out, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ovl_revert_creds(file_inode(file_out)->i_sb, old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* Update size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) ovl_copyattr(ovl_inode_real(inode_out), inode_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) fdput(real_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) fdput(real_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static ssize_t ovl_copy_file_range(struct file *file_in, loff_t pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct file *file_out, loff_t pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) size_t len, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) OVL_COPY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct file *file_out, loff_t pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) loff_t len, unsigned int remap_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) enum ovl_copyop op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (remap_flags & REMAP_FILE_DEDUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) op = OVL_DEDUPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) op = OVL_CLONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * Don't copy up because of a dedupe request, this wouldn't make sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * most of the time (data would be duplicated instead of deduplicated).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (op == OVL_DEDUPE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) (!ovl_inode_upper(file_inode(file_in)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) !ovl_inode_upper(file_inode(file_out))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return ovl_copyfile(file_in, pos_in, file_out, pos_out, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) remap_flags, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) const struct file_operations ovl_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) .open = ovl_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .release = ovl_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .llseek = ovl_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .read_iter = ovl_read_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .write_iter = ovl_write_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .fsync = ovl_fsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) .mmap = ovl_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .fallocate = ovl_fallocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .fadvise = ovl_fadvise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .unlocked_ioctl = ovl_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .compat_ioctl = ovl_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .splice_read = generic_file_splice_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .splice_write = ovl_splice_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .copy_file_range = ovl_copy_file_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .remap_file_range = ovl_remap_file_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int __init ovl_aio_request_cache_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ovl_aio_request_cachep = kmem_cache_create("ovl_aio_req",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) sizeof(struct ovl_aio_req),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 0, SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (!ovl_aio_request_cachep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) void ovl_aio_request_cache_destroy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) kmem_cache_destroy(ovl_aio_request_cachep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }