^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/read_write.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/sched/xacct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/fsnotify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/splice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const struct file_operations generic_ro_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .read_iter = generic_file_read_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .mmap = generic_file_readonly_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .splice_read = generic_file_splice_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) EXPORT_SYMBOL(generic_ro_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static inline bool unsigned_offsets(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return file->f_mode & FMODE_UNSIGNED_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * vfs_setpos - update the file offset for lseek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @file: file structure in question
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @offset: file offset to seek to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @maxsize: maximum file size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * This is a low-level filesystem helper for updating the file offset to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * the value specified by @offset if the given offset is valid and it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * not equal to the current file offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Return the specified offset on success and -EINVAL on invalid offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (offset < 0 && !unsigned_offsets(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (offset > maxsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (offset != file->f_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) file->f_pos = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) file->f_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) EXPORT_SYMBOL(vfs_setpos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * generic_file_llseek_size - generic llseek implementation for regular files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * @file: file structure to seek on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * @offset: file offset to seek to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @whence: type of seek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @size: max size of this file in file system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * @eof: offset used for SEEK_END position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * This is a variant of generic_file_llseek that allows passing in a custom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * maximum file size and a custom EOF position, for e.g. hashed directories
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Synchronization:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * SEEK_SET and SEEK_END are unsynchronized (but atomic on 64bit platforms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * SEEK_CUR is synchronized against other SEEK_CURs, but not read/writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * read/writes behave like SEEK_SET against seeks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) loff_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) generic_file_llseek_size(struct file *file, loff_t offset, int whence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) loff_t maxsize, loff_t eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) offset += eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Here we special-case the lseek(fd, 0, SEEK_CUR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * position-querying operation. Avoid rewriting the "same"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * f_pos value back to the file because a concurrent read(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * write() or lseek() might have altered it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (offset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * f_lock protects against read/modify/write race with other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * SEEK_CURs. Note that parallel writes and reads behave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * like SEEK_SET.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) spin_lock(&file->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) offset = vfs_setpos(file, file->f_pos + offset, maxsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) spin_unlock(&file->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case SEEK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * In the generic case the entire file is data, so as long as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * offset isn't at the end of the file then the offset is data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if ((unsigned long long)offset >= eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case SEEK_HOLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * There is a virtual hole at the end of the file, so as long as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * offset isn't i_size or larger, return i_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if ((unsigned long long)offset >= eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) offset = eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return vfs_setpos(file, offset, maxsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) EXPORT_SYMBOL(generic_file_llseek_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * generic_file_llseek - generic llseek implementation for regular files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @file: file structure to seek on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @offset: file offset to seek to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @whence: type of seek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * This is a generic implemenation of ->llseek useable for all normal local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * filesystems. It just updates the file offset to the value specified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @offset and @whence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) loff_t generic_file_llseek(struct file *file, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct inode *inode = file->f_mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return generic_file_llseek_size(file, offset, whence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) inode->i_sb->s_maxbytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) i_size_read(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) EXPORT_SYMBOL(generic_file_llseek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * fixed_size_llseek - llseek implementation for fixed-sized devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @file: file structure to seek on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @offset: file offset to seek to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @whence: type of seek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @size: size of the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) loff_t fixed_size_llseek(struct file *file, loff_t offset, int whence, loff_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case SEEK_SET: case SEEK_CUR: case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return generic_file_llseek_size(file, offset, whence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) EXPORT_SYMBOL(fixed_size_llseek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * no_seek_end_llseek - llseek implementation for fixed-sized devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @file: file structure to seek on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * @offset: file offset to seek to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * @whence: type of seek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) loff_t no_seek_end_llseek(struct file *file, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case SEEK_SET: case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return generic_file_llseek_size(file, offset, whence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) OFFSET_MAX, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) EXPORT_SYMBOL(no_seek_end_llseek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * no_seek_end_llseek_size - llseek implementation for fixed-sized devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @file: file structure to seek on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @offset: file offset to seek to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @whence: type of seek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @size: maximal offset allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) loff_t no_seek_end_llseek_size(struct file *file, loff_t offset, int whence, loff_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case SEEK_SET: case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return generic_file_llseek_size(file, offset, whence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) EXPORT_SYMBOL(no_seek_end_llseek_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * noop_llseek - No Operation Performed llseek implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * @file: file structure to seek on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * @offset: file offset to seek to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @whence: type of seek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * This is an implementation of ->llseek useable for the rare special case when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * userspace expects the seek to succeed but the (device) file is actually not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * able to perform the seek. In this case you use noop_llseek() instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * falling back to the default implementation of ->llseek.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) loff_t noop_llseek(struct file *file, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) EXPORT_SYMBOL(noop_llseek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) loff_t no_llseek(struct file *file, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) EXPORT_SYMBOL(no_llseek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) loff_t default_llseek(struct file *file, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) loff_t retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case SEEK_END:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) offset += i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) retval = file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) offset += file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case SEEK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * In the generic case the entire file is data, so as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * long as offset isn't at the end of the file then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * offset is data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (offset >= inode->i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) retval = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case SEEK_HOLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * There is a virtual hole at the end of the file, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * as long as offset isn't i_size or larger, return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * i_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (offset >= inode->i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) retval = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) offset = inode->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (offset >= 0 || unsigned_offsets(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (offset != file->f_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) file->f_pos = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) file->f_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) retval = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) EXPORT_SYMBOL(default_llseek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) loff_t (*fn)(struct file *, loff_t, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) fn = no_llseek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (file->f_mode & FMODE_LSEEK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (file->f_op->llseek)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) fn = file->f_op->llseek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return fn(file, offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) EXPORT_SYMBOL(vfs_llseek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) off_t retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct fd f = fdget_pos(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (whence <= SEEK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) loff_t res = vfs_llseek(f.file, offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) retval = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (res != (loff_t)retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) fdput_pos(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ksys_lseek(fd, offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned int, whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return ksys_lseek(fd, offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) defined(__ARCH_WANT_SYS_LLSEEK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned long, offset_low, loff_t __user *, result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned int, whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct fd f = fdget_pos(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) loff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (whence > SEEK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto out_putf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) offset = vfs_llseek(f.file, ((loff_t) offset_high << 32) | offset_low,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) retval = (int)offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (offset >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) retval = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!copy_to_user(result, &offset, sizeof(offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) out_putf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) fdput_pos(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (unlikely((ssize_t) count < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * ranged mandatory locking does not apply to streams - it makes sense
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * only for files where position has a meaning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (ppos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) loff_t pos = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (unlikely(pos < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!unsigned_offsets(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (count >= -pos) /* both values are in 0..LLONG_MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) } else if (unlikely((loff_t) (pos + count) < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!unsigned_offsets(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (unlikely(inode->i_flctx && mandatory_lock(inode))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) retval = locks_mandatory_area(inode, file, pos, pos + count - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) read_write == READ ? F_RDLCK : F_WRLCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return security_file_permission(file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) read_write == READ ? MAY_READ : MAY_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct iovec iov = { .iov_base = buf, .iov_len = len };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct kiocb kiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) init_sync_kiocb(&kiocb, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) kiocb.ki_pos = (ppos ? *ppos : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) iov_iter_init(&iter, READ, &iov, 1, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ret = call_read_iter(filp, &kiocb, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) BUG_ON(ret == -EIOCBQUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) *ppos = kiocb.ki_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int warn_unsupported(struct file *file, const char *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) pr_warn_ratelimited(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) "kernel %s not supported for file %pD4 (pid: %d comm: %.20s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) op, file, current->pid, current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct kvec iov = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .iov_base = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .iov_len = min_t(size_t, count, MAX_RW_COUNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct kiocb kiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (WARN_ON_ONCE(!(file->f_mode & FMODE_READ)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (!(file->f_mode & FMODE_CAN_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * Also fail if ->read_iter and ->read are both wired up as that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * implies very convoluted semantics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (unlikely(!file->f_op->read_iter || file->f_op->read))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return warn_unsupported(file, "read");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) init_sync_kiocb(&kiocb, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) kiocb.ki_pos = pos ? *pos : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) iov_iter_kvec(&iter, READ, &iov, 1, iov.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ret = file->f_op->read_iter(&kiocb, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *pos = kiocb.ki_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) fsnotify_access(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) add_rchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) inc_syscr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ret = rw_verify_area(READ, file, pos, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return __kernel_read(file, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) EXPORT_SYMBOL_NS(kernel_read, ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (!(file->f_mode & FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (!(file->f_mode & FMODE_CAN_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (unlikely(!access_ok(buf, count)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret = rw_verify_area(READ, file, pos, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (count > MAX_RW_COUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) count = MAX_RW_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (file->f_op->read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = file->f_op->read(file, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) else if (file->f_op->read_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = new_sync_read(file, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) fsnotify_access(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) add_rchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) inc_syscr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct kiocb kiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) init_sync_kiocb(&kiocb, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) kiocb.ki_pos = (ppos ? *ppos : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) iov_iter_init(&iter, WRITE, &iov, 1, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ret = call_write_iter(filp, &kiocb, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) BUG_ON(ret == -EIOCBQUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (ret > 0 && ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *ppos = kiocb.ki_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* caller is responsible for file_start_write/file_end_write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct kvec iov = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .iov_base = (void *)buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .iov_len = min_t(size_t, count, MAX_RW_COUNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct kiocb kiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (WARN_ON_ONCE(!(file->f_mode & FMODE_WRITE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (!(file->f_mode & FMODE_CAN_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * Also fail if ->write_iter and ->write are both wired up as that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * implies very convoluted semantics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (unlikely(!file->f_op->write_iter || file->f_op->write))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return warn_unsupported(file, "write");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) init_sync_kiocb(&kiocb, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) kiocb.ki_pos = pos ? *pos : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = file->f_op->write_iter(&kiocb, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *pos = kiocb.ki_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) fsnotify_modify(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) add_wchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) inc_syscw(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * This "EXPORT_SYMBOL_GPL()" is more of a "EXPORT_SYMBOL_DONTUSE()",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * but autofs is one of the few internal kernel users that actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * wants this _and_ can be built as a module. So we need to export
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * this symbol for autofs, even though it really isn't appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * for any other kernel modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) EXPORT_SYMBOL_GPL(__kernel_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ssize_t kernel_write(struct file *file, const void *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ret = rw_verify_area(WRITE, file, pos, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) file_start_write(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ret = __kernel_write(file, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) file_end_write(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) EXPORT_SYMBOL_NS(kernel_write, ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (!(file->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!(file->f_mode & FMODE_CAN_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (unlikely(!access_ok(buf, count)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ret = rw_verify_area(WRITE, file, pos, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (count > MAX_RW_COUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) count = MAX_RW_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) file_start_write(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (file->f_op->write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = file->f_op->write(file, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) else if (file->f_op->write_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ret = new_sync_write(file, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) fsnotify_modify(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) add_wchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) inc_syscw(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) file_end_write(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* file_ppos returns &file->f_pos or NULL if file is stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static inline loff_t *file_ppos(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return file->f_mode & FMODE_STREAM ? NULL : &file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct fd f = fdget_pos(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) loff_t pos, *ppos = file_ppos(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (ppos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) pos = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ppos = &pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ret = vfs_read(f.file, buf, count, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (ret >= 0 && ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) f.file->f_pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) fdput_pos(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return ksys_read(fd, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct fd f = fdget_pos(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) loff_t pos, *ppos = file_ppos(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (ppos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) pos = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ppos = &pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ret = vfs_write(f.file, buf, count, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (ret >= 0 && ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) f.file->f_pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) fdput_pos(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) size_t, count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return ksys_write(fd, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) loff_t pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (f.file->f_mode & FMODE_PREAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ret = vfs_read(f.file, buf, count, &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) size_t, count, loff_t, pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return ksys_pread64(fd, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) size_t count, loff_t pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ret = -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (f.file->f_mode & FMODE_PWRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ret = vfs_write(f.file, buf, count, &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) size_t, count, loff_t, pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return ksys_pwrite64(fd, buf, count, pos);
^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 ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) loff_t *ppos, int type, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct kiocb kiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) init_sync_kiocb(&kiocb, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ret = kiocb_set_rw_flags(&kiocb, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) kiocb.ki_pos = (ppos ? *ppos : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (type == READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret = call_read_iter(filp, &kiocb, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ret = call_write_iter(filp, &kiocb, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) BUG_ON(ret == -EIOCBQUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) *ppos = kiocb.ki_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* Do it by hand, with file-ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) loff_t *ppos, int type, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (flags & ~RWF_HIPRI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) while (iov_iter_count(iter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct iovec iovec = iov_iter_iovec(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ssize_t nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (type == READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) nr = filp->f_op->read(filp, iovec.iov_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) iovec.iov_len, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) nr = filp->f_op->write(filp, iovec.iov_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) iovec.iov_len, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (nr < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ret = nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ret += nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (nr != iovec.iov_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) iov_iter_advance(iter, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) static ssize_t do_iter_read(struct file *file, struct iov_iter *iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) loff_t *pos, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) size_t tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!(file->f_mode & FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!(file->f_mode & FMODE_CAN_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) tot_len = iov_iter_count(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!tot_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ret = rw_verify_area(READ, file, pos, tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (file->f_op->read_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ret = do_iter_readv_writev(file, iter, pos, READ, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ret = do_loop_readv_writev(file, iter, pos, READ, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) fsnotify_access(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ssize_t vfs_iocb_iter_read(struct file *file, struct kiocb *iocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct iov_iter *iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) size_t tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!file->f_op->read_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (!(file->f_mode & FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (!(file->f_mode & FMODE_CAN_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) tot_len = iov_iter_count(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (!tot_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ret = rw_verify_area(READ, file, &iocb->ki_pos, tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ret = call_read_iter(file, iocb, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) fsnotify_access(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) EXPORT_SYMBOL(vfs_iocb_iter_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (!file->f_op->read_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return do_iter_read(file, iter, ppos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) EXPORT_SYMBOL(vfs_iter_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static ssize_t do_iter_write(struct file *file, struct iov_iter *iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) loff_t *pos, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) size_t tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (!(file->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!(file->f_mode & FMODE_CAN_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) tot_len = iov_iter_count(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (!tot_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) ret = rw_verify_area(WRITE, file, pos, tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (file->f_op->write_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ret = do_iter_readv_writev(file, iter, pos, WRITE, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ret = do_loop_readv_writev(file, iter, pos, WRITE, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) fsnotify_modify(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ssize_t vfs_iocb_iter_write(struct file *file, struct kiocb *iocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct iov_iter *iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) size_t tot_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (!file->f_op->write_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (!(file->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!(file->f_mode & FMODE_CAN_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) tot_len = iov_iter_count(iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!tot_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ret = rw_verify_area(WRITE, file, &iocb->ki_pos, tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ret = call_write_iter(file, iocb, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) fsnotify_modify(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) EXPORT_SYMBOL(vfs_iocb_iter_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (!file->f_op->write_iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return do_iter_write(file, iter, ppos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) EXPORT_SYMBOL(vfs_iter_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) unsigned long vlen, loff_t *pos, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct iovec iovstack[UIO_FASTIOV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) struct iovec *iov = iovstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ret = import_iovec(READ, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) ret = do_iter_read(file, &iter, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) kfree(iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) unsigned long vlen, loff_t *pos, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct iovec iovstack[UIO_FASTIOV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct iovec *iov = iovstack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct iov_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ret = import_iovec(WRITE, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) file_start_write(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ret = do_iter_write(file, &iter, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) file_end_write(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) kfree(iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) unsigned long vlen, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct fd f = fdget_pos(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) loff_t pos, *ppos = file_ppos(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (ppos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) pos = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) ppos = &pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ret = vfs_readv(f.file, vec, vlen, ppos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (ret >= 0 && ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) f.file->f_pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) fdput_pos(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) add_rchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) inc_syscr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) unsigned long vlen, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct fd f = fdget_pos(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) loff_t pos, *ppos = file_ppos(f.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (ppos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pos = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ppos = &pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ret = vfs_writev(f.file, vec, vlen, ppos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (ret >= 0 && ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) f.file->f_pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) fdput_pos(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) add_wchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) inc_syscw(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) #define HALF_LONG_BITS (BITS_PER_LONG / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static ssize_t do_preadv(unsigned long fd, const struct iovec __user *vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) unsigned long vlen, loff_t pos, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ret = -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (f.file->f_mode & FMODE_PREAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) ret = vfs_readv(f.file, vec, vlen, &pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) add_rchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) inc_syscr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static ssize_t do_pwritev(unsigned long fd, const struct iovec __user *vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) unsigned long vlen, loff_t pos, rwf_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ret = -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (f.file->f_mode & FMODE_PWRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ret = vfs_writev(f.file, vec, vlen, &pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) add_wchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) inc_syscw(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unsigned long, vlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return do_readv(fd, vec, vlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) unsigned long, vlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return do_writev(fd, vec, vlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) loff_t pos = pos_from_hilo(pos_h, pos_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return do_preadv(fd, vec, vlen, pos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) SYSCALL_DEFINE6(preadv2, unsigned long, fd, const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) rwf_t, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) loff_t pos = pos_from_hilo(pos_h, pos_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return do_readv(fd, vec, vlen, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return do_preadv(fd, vec, vlen, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) loff_t pos = pos_from_hilo(pos_h, pos_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return do_pwritev(fd, vec, vlen, pos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) rwf_t, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) loff_t pos = pos_from_hilo(pos_h, pos_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return do_writev(fd, vec, vlen, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return do_pwritev(fd, vec, vlen, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * Various compat syscalls. Note that they all pretend to take a native
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * iovec - import_iovec will properly treat those as compat_iovecs based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * in_compat_syscall().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) unsigned long, vlen, loff_t, pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return do_preadv(fd, vec, vlen, pos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) loff_t pos = ((loff_t)pos_high << 32) | pos_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return do_preadv(fd, vec, vlen, pos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) #ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) unsigned long, vlen, loff_t, pos, rwf_t, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return do_readv(fd, vec, vlen, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return do_preadv(fd, vec, vlen, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) compat_ulong_t, vlen, u32, pos_low, u32, pos_high,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) rwf_t, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) loff_t pos = ((loff_t)pos_high << 32) | pos_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return do_readv(fd, vec, vlen, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return do_preadv(fd, vec, vlen, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) unsigned long, vlen, loff_t, pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return do_pwritev(fd, vec, vlen, pos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) const struct iovec __user *,vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) loff_t pos = ((loff_t)pos_high << 32) | pos_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return do_pwritev(fd, vec, vlen, pos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) #ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) const struct iovec __user *, vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) unsigned long, vlen, loff_t, pos, rwf_t, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return do_writev(fd, vec, vlen, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return do_pwritev(fd, vec, vlen, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) const struct iovec __user *,vec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) compat_ulong_t, vlen, u32, pos_low, u32, pos_high, rwf_t, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) loff_t pos = ((loff_t)pos_high << 32) | pos_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (pos == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) return do_writev(fd, vec, vlen, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return do_pwritev(fd, vec, vlen, pos, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) #endif /* CONFIG_COMPAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) size_t count, loff_t max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct fd in, out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) struct inode *in_inode, *out_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) loff_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) loff_t out_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ssize_t retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) int fl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * Get input file, and verify that it is ok..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) retval = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) in = fdget(in_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (!in.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!(in.file->f_mode & FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) goto fput_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) retval = -ESPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (!ppos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) pos = in.file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pos = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (!(in.file->f_mode & FMODE_PREAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) goto fput_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) retval = rw_verify_area(READ, in.file, &pos, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) goto fput_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (count > MAX_RW_COUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) count = MAX_RW_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * Get output file, and verify that it is ok..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) retval = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) out = fdget(out_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (!out.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) goto fput_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (!(out.file->f_mode & FMODE_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) goto fput_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) in_inode = file_inode(in.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) out_inode = file_inode(out.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) out_pos = out.file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) retval = rw_verify_area(WRITE, out.file, &out_pos, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) goto fput_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (!max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (unlikely(pos + count > max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) retval = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (pos >= max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) goto fput_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) count = max - pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) fl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) * We need to debate whether we can enable this or not. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) * man page documents EAGAIN return for the output at least,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) * and the application is arguably buggy if it doesn't expect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) * EAGAIN on a non-blocking file descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (in.file->f_flags & O_NONBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) fl = SPLICE_F_NONBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) file_start_write(out.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) file_end_write(out.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (retval > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) add_rchar(current, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) add_wchar(current, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) fsnotify_access(in.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) fsnotify_modify(out.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) out.file->f_pos = out_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) *ppos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) in.file->f_pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) inc_syscr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) inc_syscw(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (pos > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) retval = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) fput_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) fdput(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) fput_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) fdput(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) loff_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) off_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (unlikely(get_user(off, offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) pos = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (unlikely(put_user(pos, offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return do_sendfile(out_fd, in_fd, NULL, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) loff_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (unlikely(put_user(pos, offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) return do_sendfile(out_fd, in_fd, NULL, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) COMPAT_SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) compat_off_t __user *, offset, compat_size_t, count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) loff_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) off_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (unlikely(get_user(off, offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) pos = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (unlikely(put_user(pos, offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return do_sendfile(out_fd, in_fd, NULL, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) compat_loff_t __user *, offset, compat_size_t, count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) loff_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (unlikely(put_user(pos, offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return do_sendfile(out_fd, in_fd, NULL, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) * generic_copy_file_range - copy data between two files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) * @file_in: file structure to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) * @pos_in: file offset to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * @file_out: file structure to write data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * @pos_out: file offset to write data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * @len: amount of data to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * @flags: copy flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * This is a generic filesystem helper to copy data from one file to another.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * It has no constraints on the source or destination file owners - the files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * can belong to different superblocks and different filesystem types. Short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * copies are allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) * This should be called from the @file_out filesystem, as per the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * ->copy_file_range() method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) * Returns the number of bytes copied or a negative error indicating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct file *file_out, loff_t pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) size_t len, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return do_splice_direct(file_in, &pos_in, file_out, &pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) EXPORT_SYMBOL(generic_copy_file_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) static ssize_t do_copy_file_range(struct file *file_in, loff_t pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) struct file *file_out, loff_t pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) size_t len, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) * Although we now allow filesystems to handle cross sb copy, passing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) * a file of the wrong filesystem type to filesystem driver can result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) * in an attempt to dereference the wrong type of ->private_data, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * avoid doing that until we really have a good reason. NFS defines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) * several different file_system_type structures, but they all end up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * using the same ->copy_file_range() function pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (file_out->f_op->copy_file_range &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) file_out->f_op->copy_file_range == file_in->f_op->copy_file_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return file_out->f_op->copy_file_range(file_in, pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) file_out, pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return generic_copy_file_range(file_in, pos_in, file_out, pos_out, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) * Performs necessary checks before doing a file copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) * Can adjust amount of bytes to copy via @req_count argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) * Returns appropriate error code that caller should return or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * zero in case the copy should be allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) struct file *file_out, loff_t pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) size_t *req_count, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) struct inode *inode_in = file_inode(file_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) struct inode *inode_out = file_inode(file_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) uint64_t count = *req_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) loff_t size_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) ret = generic_file_rw_checks(file_in, file_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) /* Don't touch certain kinds of inodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (IS_IMMUTABLE(inode_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (IS_SWAPFILE(inode_in) || IS_SWAPFILE(inode_out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) return -ETXTBSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* Ensure offsets don't wrap. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (pos_in + count < pos_in || pos_out + count < pos_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) return -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /* Shorten the copy to EOF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) size_in = i_size_read(inode_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (pos_in >= size_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) count = min(count, size_in - (uint64_t)pos_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) ret = generic_write_check_limits(file_out, pos_out, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) /* Don't allow overlapped copying within the same file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (inode_in == inode_out &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) pos_out + count > pos_in &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) pos_out < pos_in + count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) *req_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * copy_file_range() differs from regular file read and write in that it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * specifically allows return partial success. When it does so is up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * the copy_file_range method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) struct file *file_out, loff_t pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) size_t len, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (flags != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) ret = rw_verify_area(READ, file_in, &pos_in, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ret = rw_verify_area(WRITE, file_out, &pos_out, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (unlikely(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) file_start_write(file_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * Try cloning first, this is supported by more file systems, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) * more efficient if both clone and copy are supported (e.g. NFS).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (file_in->f_op->remap_file_range &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) file_inode(file_in)->i_sb == file_inode(file_out)->i_sb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) loff_t cloned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) cloned = file_in->f_op->remap_file_range(file_in, pos_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) file_out, pos_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) min_t(loff_t, MAX_RW_COUNT, len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) REMAP_FILE_CAN_SHORTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (cloned > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) ret = cloned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) ret = do_copy_file_range(file_in, pos_in, file_out, pos_out, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) WARN_ON_ONCE(ret == -EOPNOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) fsnotify_access(file_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) add_rchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) fsnotify_modify(file_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) add_wchar(current, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) inc_syscr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) inc_syscw(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) file_end_write(file_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) EXPORT_SYMBOL(vfs_copy_file_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) SYSCALL_DEFINE6(copy_file_range, int, fd_in, loff_t __user *, off_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) int, fd_out, loff_t __user *, off_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) size_t, len, unsigned int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) loff_t pos_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) loff_t pos_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) struct fd f_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct fd f_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) ssize_t ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) f_in = fdget(fd_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) if (!f_in.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) f_out = fdget(fd_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (!f_out.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (off_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (copy_from_user(&pos_in, off_in, sizeof(loff_t)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) pos_in = f_in.file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (off_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (copy_from_user(&pos_out, off_out, sizeof(loff_t)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) pos_out = f_out.file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) ret = vfs_copy_file_range(f_in.file, pos_in, f_out.file, pos_out, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) pos_in += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) pos_out += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if (off_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (copy_to_user(off_in, &pos_in, sizeof(loff_t)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) f_in.file->f_pos = pos_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) if (off_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (copy_to_user(off_out, &pos_out, sizeof(loff_t)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) f_out.file->f_pos = pos_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) fdput(f_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) fdput(f_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) * Don't operate on ranges the page cache doesn't support, and don't exceed the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * LFS limits. If pos is under the limit it becomes a short access. If it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * exceeds the limit we return -EFBIG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) int generic_write_check_limits(struct file *file, loff_t pos, loff_t *count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) struct inode *inode = file->f_mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) loff_t max_size = inode->i_sb->s_maxbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) loff_t limit = rlimit(RLIMIT_FSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (limit != RLIM_INFINITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (pos >= limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) send_sig(SIGXFSZ, current, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) return -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) *count = min(*count, limit - pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (!(file->f_flags & O_LARGEFILE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) max_size = MAX_NON_LFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) if (unlikely(pos >= max_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return -EFBIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) *count = min(*count, max_size - pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * Performs necessary checks before doing a write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * Can adjust writing position or amount of bytes to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * Returns appropriate error code that caller should return or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) * zero in case that write should be allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) struct file *file = iocb->ki_filp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) struct inode *inode = file->f_mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) loff_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (IS_SWAPFILE(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) return -ETXTBSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (!iov_iter_count(from))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /* FIXME: this is for backwards compatibility with 2.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (iocb->ki_flags & IOCB_APPEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) iocb->ki_pos = i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) count = iov_iter_count(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) ret = generic_write_check_limits(file, iocb->ki_pos, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) iov_iter_truncate(from, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) return iov_iter_count(from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) EXPORT_SYMBOL(generic_write_checks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * Performs common checks before doing a file copy/clone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) * from @file_in to @file_out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) int generic_file_rw_checks(struct file *file_in, struct file *file_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct inode *inode_in = file_inode(file_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct inode *inode_out = file_inode(file_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) /* Don't copy dirs, pipes, sockets... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) return -EISDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (!(file_in->f_mode & FMODE_READ) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) !(file_out->f_mode & FMODE_WRITE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) (file_out->f_flags & O_APPEND))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) }