diff options
-rw-r--r-- | fs/nfsd/vfs.c | 4 | ||||
-rw-r--r-- | fs/read_write.c | 44 | ||||
-rw-r--r-- | fs/splice.c | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 4 |
4 files changed, 31 insertions, 23 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 5d2a57e4c03a..d40010e4f1a9 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -870,7 +870,7 @@ __be32 nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen, | |||
870 | 870 | ||
871 | oldfs = get_fs(); | 871 | oldfs = get_fs(); |
872 | set_fs(KERNEL_DS); | 872 | set_fs(KERNEL_DS); |
873 | host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset); | 873 | host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset, 0); |
874 | set_fs(oldfs); | 874 | set_fs(oldfs); |
875 | return nfsd_finish_read(file, count, host_err); | 875 | return nfsd_finish_read(file, count, host_err); |
876 | } | 876 | } |
@@ -957,7 +957,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
957 | 957 | ||
958 | /* Write the data. */ | 958 | /* Write the data. */ |
959 | oldfs = get_fs(); set_fs(KERNEL_DS); | 959 | oldfs = get_fs(); set_fs(KERNEL_DS); |
960 | host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos); | 960 | host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos, 0); |
961 | set_fs(oldfs); | 961 | set_fs(oldfs); |
962 | if (host_err < 0) | 962 | if (host_err < 0) |
963 | goto out_nfserr; | 963 | goto out_nfserr; |
diff --git a/fs/read_write.c b/fs/read_write.c index 324ec271cc4e..7d453c3e1cb6 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -692,11 +692,14 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) | |||
692 | EXPORT_SYMBOL(iov_shorten); | 692 | EXPORT_SYMBOL(iov_shorten); |
693 | 693 | ||
694 | static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | 694 | static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, |
695 | loff_t *ppos, iter_fn_t fn) | 695 | loff_t *ppos, iter_fn_t fn, int flags) |
696 | { | 696 | { |
697 | struct kiocb kiocb; | 697 | struct kiocb kiocb; |
698 | ssize_t ret; | 698 | ssize_t ret; |
699 | 699 | ||
700 | if (flags) | ||
701 | return -EOPNOTSUPP; | ||
702 | |||
700 | init_sync_kiocb(&kiocb, filp); | 703 | init_sync_kiocb(&kiocb, filp); |
701 | kiocb.ki_pos = *ppos; | 704 | kiocb.ki_pos = *ppos; |
702 | 705 | ||
@@ -708,10 +711,13 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, | |||
708 | 711 | ||
709 | /* Do it by hand, with file-ops */ | 712 | /* Do it by hand, with file-ops */ |
710 | static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, | 713 | static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, |
711 | loff_t *ppos, io_fn_t fn) | 714 | loff_t *ppos, io_fn_t fn, int flags) |
712 | { | 715 | { |
713 | ssize_t ret = 0; | 716 | ssize_t ret = 0; |
714 | 717 | ||
718 | if (flags) | ||
719 | return -EOPNOTSUPP; | ||
720 | |||
715 | while (iov_iter_count(iter)) { | 721 | while (iov_iter_count(iter)) { |
716 | struct iovec iovec = iov_iter_iovec(iter); | 722 | struct iovec iovec = iov_iter_iovec(iter); |
717 | ssize_t nr; | 723 | ssize_t nr; |
@@ -812,7 +818,8 @@ out: | |||
812 | 818 | ||
813 | static ssize_t do_readv_writev(int type, struct file *file, | 819 | static ssize_t do_readv_writev(int type, struct file *file, |
814 | const struct iovec __user * uvector, | 820 | const struct iovec __user * uvector, |
815 | unsigned long nr_segs, loff_t *pos) | 821 | unsigned long nr_segs, loff_t *pos, |
822 | int flags) | ||
816 | { | 823 | { |
817 | size_t tot_len; | 824 | size_t tot_len; |
818 | struct iovec iovstack[UIO_FASTIOV]; | 825 | struct iovec iovstack[UIO_FASTIOV]; |
@@ -844,9 +851,9 @@ static ssize_t do_readv_writev(int type, struct file *file, | |||
844 | } | 851 | } |
845 | 852 | ||
846 | if (iter_fn) | 853 | if (iter_fn) |
847 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn); | 854 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags); |
848 | else | 855 | else |
849 | ret = do_loop_readv_writev(file, &iter, pos, fn); | 856 | ret = do_loop_readv_writev(file, &iter, pos, fn, flags); |
850 | 857 | ||
851 | if (type != READ) | 858 | if (type != READ) |
852 | file_end_write(file); | 859 | file_end_write(file); |
@@ -863,27 +870,27 @@ out: | |||
863 | } | 870 | } |
864 | 871 | ||
865 | ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, | 872 | ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, |
866 | unsigned long vlen, loff_t *pos) | 873 | unsigned long vlen, loff_t *pos, int flags) |
867 | { | 874 | { |
868 | if (!(file->f_mode & FMODE_READ)) | 875 | if (!(file->f_mode & FMODE_READ)) |
869 | return -EBADF; | 876 | return -EBADF; |
870 | if (!(file->f_mode & FMODE_CAN_READ)) | 877 | if (!(file->f_mode & FMODE_CAN_READ)) |
871 | return -EINVAL; | 878 | return -EINVAL; |
872 | 879 | ||
873 | return do_readv_writev(READ, file, vec, vlen, pos); | 880 | return do_readv_writev(READ, file, vec, vlen, pos, flags); |
874 | } | 881 | } |
875 | 882 | ||
876 | EXPORT_SYMBOL(vfs_readv); | 883 | EXPORT_SYMBOL(vfs_readv); |
877 | 884 | ||
878 | ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, | 885 | ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, |
879 | unsigned long vlen, loff_t *pos) | 886 | unsigned long vlen, loff_t *pos, int flags) |
880 | { | 887 | { |
881 | if (!(file->f_mode & FMODE_WRITE)) | 888 | if (!(file->f_mode & FMODE_WRITE)) |
882 | return -EBADF; | 889 | return -EBADF; |
883 | if (!(file->f_mode & FMODE_CAN_WRITE)) | 890 | if (!(file->f_mode & FMODE_CAN_WRITE)) |
884 | return -EINVAL; | 891 | return -EINVAL; |
885 | 892 | ||
886 | return do_readv_writev(WRITE, file, vec, vlen, pos); | 893 | return do_readv_writev(WRITE, file, vec, vlen, pos, flags); |
887 | } | 894 | } |
888 | 895 | ||
889 | EXPORT_SYMBOL(vfs_writev); | 896 | EXPORT_SYMBOL(vfs_writev); |
@@ -896,7 +903,7 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | |||
896 | 903 | ||
897 | if (f.file) { | 904 | if (f.file) { |
898 | loff_t pos = file_pos_read(f.file); | 905 | loff_t pos = file_pos_read(f.file); |
899 | ret = vfs_readv(f.file, vec, vlen, &pos); | 906 | ret = vfs_readv(f.file, vec, vlen, &pos, 0); |
900 | if (ret >= 0) | 907 | if (ret >= 0) |
901 | file_pos_write(f.file, pos); | 908 | file_pos_write(f.file, pos); |
902 | fdput_pos(f); | 909 | fdput_pos(f); |
@@ -916,7 +923,7 @@ SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, | |||
916 | 923 | ||
917 | if (f.file) { | 924 | if (f.file) { |
918 | loff_t pos = file_pos_read(f.file); | 925 | loff_t pos = file_pos_read(f.file); |
919 | ret = vfs_writev(f.file, vec, vlen, &pos); | 926 | ret = vfs_writev(f.file, vec, vlen, &pos, 0); |
920 | if (ret >= 0) | 927 | if (ret >= 0) |
921 | file_pos_write(f.file, pos); | 928 | file_pos_write(f.file, pos); |
922 | fdput_pos(f); | 929 | fdput_pos(f); |
@@ -948,7 +955,7 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, | |||
948 | if (f.file) { | 955 | if (f.file) { |
949 | ret = -ESPIPE; | 956 | ret = -ESPIPE; |
950 | if (f.file->f_mode & FMODE_PREAD) | 957 | if (f.file->f_mode & FMODE_PREAD) |
951 | ret = vfs_readv(f.file, vec, vlen, &pos); | 958 | ret = vfs_readv(f.file, vec, vlen, &pos, 0); |
952 | fdput(f); | 959 | fdput(f); |
953 | } | 960 | } |
954 | 961 | ||
@@ -972,7 +979,7 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
972 | if (f.file) { | 979 | if (f.file) { |
973 | ret = -ESPIPE; | 980 | ret = -ESPIPE; |
974 | if (f.file->f_mode & FMODE_PWRITE) | 981 | if (f.file->f_mode & FMODE_PWRITE) |
975 | ret = vfs_writev(f.file, vec, vlen, &pos); | 982 | ret = vfs_writev(f.file, vec, vlen, &pos, 0); |
976 | fdput(f); | 983 | fdput(f); |
977 | } | 984 | } |
978 | 985 | ||
@@ -986,7 +993,8 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, | |||
986 | 993 | ||
987 | static ssize_t compat_do_readv_writev(int type, struct file *file, | 994 | static ssize_t compat_do_readv_writev(int type, struct file *file, |
988 | const struct compat_iovec __user *uvector, | 995 | const struct compat_iovec __user *uvector, |
989 | unsigned long nr_segs, loff_t *pos) | 996 | unsigned long nr_segs, loff_t *pos, |
997 | int flags) | ||
990 | { | 998 | { |
991 | compat_ssize_t tot_len; | 999 | compat_ssize_t tot_len; |
992 | struct iovec iovstack[UIO_FASTIOV]; | 1000 | struct iovec iovstack[UIO_FASTIOV]; |
@@ -1018,9 +1026,9 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1018 | } | 1026 | } |
1019 | 1027 | ||
1020 | if (iter_fn) | 1028 | if (iter_fn) |
1021 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn); | 1029 | ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags); |
1022 | else | 1030 | else |
1023 | ret = do_loop_readv_writev(file, &iter, pos, fn); | 1031 | ret = do_loop_readv_writev(file, &iter, pos, fn, flags); |
1024 | 1032 | ||
1025 | if (type != READ) | 1033 | if (type != READ) |
1026 | file_end_write(file); | 1034 | file_end_write(file); |
@@ -1049,7 +1057,7 @@ static size_t compat_readv(struct file *file, | |||
1049 | if (!(file->f_mode & FMODE_CAN_READ)) | 1057 | if (!(file->f_mode & FMODE_CAN_READ)) |
1050 | goto out; | 1058 | goto out; |
1051 | 1059 | ||
1052 | ret = compat_do_readv_writev(READ, file, vec, vlen, pos); | 1060 | ret = compat_do_readv_writev(READ, file, vec, vlen, pos, 0); |
1053 | 1061 | ||
1054 | out: | 1062 | out: |
1055 | if (ret > 0) | 1063 | if (ret > 0) |
@@ -1126,7 +1134,7 @@ static size_t compat_writev(struct file *file, | |||
1126 | if (!(file->f_mode & FMODE_CAN_WRITE)) | 1134 | if (!(file->f_mode & FMODE_CAN_WRITE)) |
1127 | goto out; | 1135 | goto out; |
1128 | 1136 | ||
1129 | ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos); | 1137 | ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos, 0); |
1130 | 1138 | ||
1131 | out: | 1139 | out: |
1132 | if (ret > 0) | 1140 | if (ret > 0) |
diff --git a/fs/splice.c b/fs/splice.c index 82bc0d64fc38..3dc142637ab5 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -577,7 +577,7 @@ static ssize_t kernel_readv(struct file *file, const struct iovec *vec, | |||
577 | old_fs = get_fs(); | 577 | old_fs = get_fs(); |
578 | set_fs(get_ds()); | 578 | set_fs(get_ds()); |
579 | /* The cast to a user pointer is valid due to the set_fs() */ | 579 | /* The cast to a user pointer is valid due to the set_fs() */ |
580 | res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos); | 580 | res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos, 0); |
581 | set_fs(old_fs); | 581 | set_fs(old_fs); |
582 | 582 | ||
583 | return res; | 583 | return res; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 1a2046275cdf..6ec87964644f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1712,9 +1712,9 @@ extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *) | |||
1712 | extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); | 1712 | extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); |
1713 | extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); | 1713 | extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); |
1714 | extern ssize_t vfs_readv(struct file *, const struct iovec __user *, | 1714 | extern ssize_t vfs_readv(struct file *, const struct iovec __user *, |
1715 | unsigned long, loff_t *); | 1715 | unsigned long, loff_t *, int); |
1716 | extern ssize_t vfs_writev(struct file *, const struct iovec __user *, | 1716 | extern ssize_t vfs_writev(struct file *, const struct iovec __user *, |
1717 | unsigned long, loff_t *); | 1717 | unsigned long, loff_t *, int); |
1718 | extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, | 1718 | extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, |
1719 | loff_t, size_t, unsigned int); | 1719 | loff_t, size_t, unsigned int); |
1720 | extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, | 1720 | extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, |