LCOV - code coverage report
Current view: top level - fs - read_write.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 354 775 45.7 %
Date: 2021-04-22 12:43:58 Functions: 34 102 33.3 %

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

Generated by: LCOV version 1.14