aboutsummaryrefslogtreecommitdiffstats
path: root/fs/read_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/read_write.c')
-rw-r--r--fs/read_write.c197
1 files changed, 149 insertions, 48 deletions
diff --git a/fs/read_write.c b/fs/read_write.c
index dadf24e5c95b..cf377cf9dfe3 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -693,12 +693,17 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
693EXPORT_SYMBOL(iov_shorten); 693EXPORT_SYMBOL(iov_shorten);
694 694
695static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, 695static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
696 loff_t *ppos, iter_fn_t fn) 696 loff_t *ppos, iter_fn_t fn, int flags)
697{ 697{
698 struct kiocb kiocb; 698 struct kiocb kiocb;
699 ssize_t ret; 699 ssize_t ret;
700 700
701 if (flags & ~RWF_HIPRI)
702 return -EOPNOTSUPP;
703
701 init_sync_kiocb(&kiocb, filp); 704 init_sync_kiocb(&kiocb, filp);
705 if (flags & RWF_HIPRI)
706 kiocb.ki_flags |= IOCB_HIPRI;
702 kiocb.ki_pos = *ppos; 707 kiocb.ki_pos = *ppos;
703 708
704 ret = fn(&kiocb, iter); 709 ret = fn(&kiocb, iter);
@@ -709,10 +714,13 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
709 714
710/* Do it by hand, with file-ops */ 715/* Do it by hand, with file-ops */
711static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, 716static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
712 loff_t *ppos, io_fn_t fn) 717 loff_t *ppos, io_fn_t fn, int flags)
713{ 718{
714 ssize_t ret = 0; 719 ssize_t ret = 0;
715 720
721 if (flags & ~RWF_HIPRI)
722 return -EOPNOTSUPP;
723
716 while (iov_iter_count(iter)) { 724 while (iov_iter_count(iter)) {
717 struct iovec iovec = iov_iter_iovec(iter); 725 struct iovec iovec = iov_iter_iovec(iter);
718 ssize_t nr; 726 ssize_t nr;
@@ -813,7 +821,8 @@ out:
813 821
814static ssize_t do_readv_writev(int type, struct file *file, 822static ssize_t do_readv_writev(int type, struct file *file,
815 const struct iovec __user * uvector, 823 const struct iovec __user * uvector,
816 unsigned long nr_segs, loff_t *pos) 824 unsigned long nr_segs, loff_t *pos,
825 int flags)
817{ 826{
818 size_t tot_len; 827 size_t tot_len;
819 struct iovec iovstack[UIO_FASTIOV]; 828 struct iovec iovstack[UIO_FASTIOV];
@@ -845,9 +854,9 @@ static ssize_t do_readv_writev(int type, struct file *file,
845 } 854 }
846 855
847 if (iter_fn) 856 if (iter_fn)
848 ret = do_iter_readv_writev(file, &iter, pos, iter_fn); 857 ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags);
849 else 858 else
850 ret = do_loop_readv_writev(file, &iter, pos, fn); 859 ret = do_loop_readv_writev(file, &iter, pos, fn, flags);
851 860
852 if (type != READ) 861 if (type != READ)
853 file_end_write(file); 862 file_end_write(file);
@@ -864,40 +873,40 @@ out:
864} 873}
865 874
866ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, 875ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
867 unsigned long vlen, loff_t *pos) 876 unsigned long vlen, loff_t *pos, int flags)
868{ 877{
869 if (!(file->f_mode & FMODE_READ)) 878 if (!(file->f_mode & FMODE_READ))
870 return -EBADF; 879 return -EBADF;
871 if (!(file->f_mode & FMODE_CAN_READ)) 880 if (!(file->f_mode & FMODE_CAN_READ))
872 return -EINVAL; 881 return -EINVAL;
873 882
874 return do_readv_writev(READ, file, vec, vlen, pos); 883 return do_readv_writev(READ, file, vec, vlen, pos, flags);
875} 884}
876 885
877EXPORT_SYMBOL(vfs_readv); 886EXPORT_SYMBOL(vfs_readv);
878 887
879ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, 888ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
880 unsigned long vlen, loff_t *pos) 889 unsigned long vlen, loff_t *pos, int flags)
881{ 890{
882 if (!(file->f_mode & FMODE_WRITE)) 891 if (!(file->f_mode & FMODE_WRITE))
883 return -EBADF; 892 return -EBADF;
884 if (!(file->f_mode & FMODE_CAN_WRITE)) 893 if (!(file->f_mode & FMODE_CAN_WRITE))
885 return -EINVAL; 894 return -EINVAL;
886 895
887 return do_readv_writev(WRITE, file, vec, vlen, pos); 896 return do_readv_writev(WRITE, file, vec, vlen, pos, flags);
888} 897}
889 898
890EXPORT_SYMBOL(vfs_writev); 899EXPORT_SYMBOL(vfs_writev);
891 900
892SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, 901static ssize_t do_readv(unsigned long fd, const struct iovec __user *vec,
893 unsigned long, vlen) 902 unsigned long vlen, int flags)
894{ 903{
895 struct fd f = fdget_pos(fd); 904 struct fd f = fdget_pos(fd);
896 ssize_t ret = -EBADF; 905 ssize_t ret = -EBADF;
897 906
898 if (f.file) { 907 if (f.file) {
899 loff_t pos = file_pos_read(f.file); 908 loff_t pos = file_pos_read(f.file);
900 ret = vfs_readv(f.file, vec, vlen, &pos); 909 ret = vfs_readv(f.file, vec, vlen, &pos, flags);
901 if (ret >= 0) 910 if (ret >= 0)
902 file_pos_write(f.file, pos); 911 file_pos_write(f.file, pos);
903 fdput_pos(f); 912 fdput_pos(f);
@@ -909,15 +918,15 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
909 return ret; 918 return ret;
910} 919}
911 920
912SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, 921static ssize_t do_writev(unsigned long fd, const struct iovec __user *vec,
913 unsigned long, vlen) 922 unsigned long vlen, int flags)
914{ 923{
915 struct fd f = fdget_pos(fd); 924 struct fd f = fdget_pos(fd);
916 ssize_t ret = -EBADF; 925 ssize_t ret = -EBADF;
917 926
918 if (f.file) { 927 if (f.file) {
919 loff_t pos = file_pos_read(f.file); 928 loff_t pos = file_pos_read(f.file);
920 ret = vfs_writev(f.file, vec, vlen, &pos); 929 ret = vfs_writev(f.file, vec, vlen, &pos, flags);
921 if (ret >= 0) 930 if (ret >= 0)
922 file_pos_write(f.file, pos); 931 file_pos_write(f.file, pos);
923 fdput_pos(f); 932 fdput_pos(f);
@@ -935,10 +944,9 @@ static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
935 return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low; 944 return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
936} 945}
937 946
938SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec, 947static ssize_t do_preadv(unsigned long fd, const struct iovec __user *vec,
939 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) 948 unsigned long vlen, loff_t pos, int flags)
940{ 949{
941 loff_t pos = pos_from_hilo(pos_h, pos_l);
942 struct fd f; 950 struct fd f;
943 ssize_t ret = -EBADF; 951 ssize_t ret = -EBADF;
944 952
@@ -949,7 +957,7 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
949 if (f.file) { 957 if (f.file) {
950 ret = -ESPIPE; 958 ret = -ESPIPE;
951 if (f.file->f_mode & FMODE_PREAD) 959 if (f.file->f_mode & FMODE_PREAD)
952 ret = vfs_readv(f.file, vec, vlen, &pos); 960 ret = vfs_readv(f.file, vec, vlen, &pos, flags);
953 fdput(f); 961 fdput(f);
954 } 962 }
955 963
@@ -959,10 +967,9 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
959 return ret; 967 return ret;
960} 968}
961 969
962SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec, 970static ssize_t do_pwritev(unsigned long fd, const struct iovec __user *vec,
963 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) 971 unsigned long vlen, loff_t pos, int flags)
964{ 972{
965 loff_t pos = pos_from_hilo(pos_h, pos_l);
966 struct fd f; 973 struct fd f;
967 ssize_t ret = -EBADF; 974 ssize_t ret = -EBADF;
968 975
@@ -973,7 +980,7 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
973 if (f.file) { 980 if (f.file) {
974 ret = -ESPIPE; 981 ret = -ESPIPE;
975 if (f.file->f_mode & FMODE_PWRITE) 982 if (f.file->f_mode & FMODE_PWRITE)
976 ret = vfs_writev(f.file, vec, vlen, &pos); 983 ret = vfs_writev(f.file, vec, vlen, &pos, flags);
977 fdput(f); 984 fdput(f);
978 } 985 }
979 986
@@ -983,11 +990,64 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
983 return ret; 990 return ret;
984} 991}
985 992
993SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
994 unsigned long, vlen)
995{
996 return do_readv(fd, vec, vlen, 0);
997}
998
999SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
1000 unsigned long, vlen)
1001{
1002 return do_writev(fd, vec, vlen, 0);
1003}
1004
1005SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
1006 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
1007{
1008 loff_t pos = pos_from_hilo(pos_h, pos_l);
1009
1010 return do_preadv(fd, vec, vlen, pos, 0);
1011}
1012
1013SYSCALL_DEFINE6(preadv2, unsigned long, fd, const struct iovec __user *, vec,
1014 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
1015 int, flags)
1016{
1017 loff_t pos = pos_from_hilo(pos_h, pos_l);
1018
1019 if (pos == -1)
1020 return do_readv(fd, vec, vlen, flags);
1021
1022 return do_preadv(fd, vec, vlen, pos, flags);
1023}
1024
1025SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
1026 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
1027{
1028 loff_t pos = pos_from_hilo(pos_h, pos_l);
1029
1030 return do_pwritev(fd, vec, vlen, pos, 0);
1031}
1032
1033SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec,
1034 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h,
1035 int, flags)
1036{
1037 loff_t pos = pos_from_hilo(pos_h, pos_l);
1038
1039 if (pos == -1)
1040 return do_writev(fd, vec, vlen, flags);
1041
1042 return do_pwritev(fd, vec, vlen, pos, flags);
1043}
1044
986#ifdef CONFIG_COMPAT 1045#ifdef CONFIG_COMPAT
987 1046
988static ssize_t compat_do_readv_writev(int type, struct file *file, 1047static ssize_t compat_do_readv_writev(int type, struct file *file,
989 const struct compat_iovec __user *uvector, 1048 const struct compat_iovec __user *uvector,
990 unsigned long nr_segs, loff_t *pos) 1049 unsigned long nr_segs, loff_t *pos,
1050 int flags)
991{ 1051{
992 compat_ssize_t tot_len; 1052 compat_ssize_t tot_len;
993 struct iovec iovstack[UIO_FASTIOV]; 1053 struct iovec iovstack[UIO_FASTIOV];
@@ -1019,9 +1079,9 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1019 } 1079 }
1020 1080
1021 if (iter_fn) 1081 if (iter_fn)
1022 ret = do_iter_readv_writev(file, &iter, pos, iter_fn); 1082 ret = do_iter_readv_writev(file, &iter, pos, iter_fn, flags);
1023 else 1083 else
1024 ret = do_loop_readv_writev(file, &iter, pos, fn); 1084 ret = do_loop_readv_writev(file, &iter, pos, fn, flags);
1025 1085
1026 if (type != READ) 1086 if (type != READ)
1027 file_end_write(file); 1087 file_end_write(file);
@@ -1039,7 +1099,7 @@ out:
1039 1099
1040static size_t compat_readv(struct file *file, 1100static size_t compat_readv(struct file *file,
1041 const struct compat_iovec __user *vec, 1101 const struct compat_iovec __user *vec,
1042 unsigned long vlen, loff_t *pos) 1102 unsigned long vlen, loff_t *pos, int flags)
1043{ 1103{
1044 ssize_t ret = -EBADF; 1104 ssize_t ret = -EBADF;
1045 1105
@@ -1050,7 +1110,7 @@ static size_t compat_readv(struct file *file,
1050 if (!(file->f_mode & FMODE_CAN_READ)) 1110 if (!(file->f_mode & FMODE_CAN_READ))
1051 goto out; 1111 goto out;
1052 1112
1053 ret = compat_do_readv_writev(READ, file, vec, vlen, pos); 1113 ret = compat_do_readv_writev(READ, file, vec, vlen, pos, flags);
1054 1114
1055out: 1115out:
1056 if (ret > 0) 1116 if (ret > 0)
@@ -1059,9 +1119,9 @@ out:
1059 return ret; 1119 return ret;
1060} 1120}
1061 1121
1062COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, 1122static size_t do_compat_readv(compat_ulong_t fd,
1063 const struct compat_iovec __user *,vec, 1123 const struct compat_iovec __user *vec,
1064 compat_ulong_t, vlen) 1124 compat_ulong_t vlen, int flags)
1065{ 1125{
1066 struct fd f = fdget_pos(fd); 1126 struct fd f = fdget_pos(fd);
1067 ssize_t ret; 1127 ssize_t ret;
@@ -1070,16 +1130,24 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
1070 if (!f.file) 1130 if (!f.file)
1071 return -EBADF; 1131 return -EBADF;
1072 pos = f.file->f_pos; 1132 pos = f.file->f_pos;
1073 ret = compat_readv(f.file, vec, vlen, &pos); 1133 ret = compat_readv(f.file, vec, vlen, &pos, flags);
1074 if (ret >= 0) 1134 if (ret >= 0)
1075 f.file->f_pos = pos; 1135 f.file->f_pos = pos;
1076 fdput_pos(f); 1136 fdput_pos(f);
1077 return ret; 1137 return ret;
1138
1139}
1140
1141COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
1142 const struct compat_iovec __user *,vec,
1143 compat_ulong_t, vlen)
1144{
1145 return do_compat_readv(fd, vec, vlen, 0);
1078} 1146}
1079 1147
1080static long __compat_sys_preadv64(unsigned long fd, 1148static long do_compat_preadv64(unsigned long fd,
1081 const struct compat_iovec __user *vec, 1149 const struct compat_iovec __user *vec,
1082 unsigned long vlen, loff_t pos) 1150 unsigned long vlen, loff_t pos, int flags)
1083{ 1151{
1084 struct fd f; 1152 struct fd f;
1085 ssize_t ret; 1153 ssize_t ret;
@@ -1091,7 +1159,7 @@ static long __compat_sys_preadv64(unsigned long fd,
1091 return -EBADF; 1159 return -EBADF;
1092 ret = -ESPIPE; 1160 ret = -ESPIPE;
1093 if (f.file->f_mode & FMODE_PREAD) 1161 if (f.file->f_mode & FMODE_PREAD)
1094 ret = compat_readv(f.file, vec, vlen, &pos); 1162 ret = compat_readv(f.file, vec, vlen, &pos, flags);
1095 fdput(f); 1163 fdput(f);
1096 return ret; 1164 return ret;
1097} 1165}
@@ -1101,7 +1169,7 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
1101 const struct compat_iovec __user *,vec, 1169 const struct compat_iovec __user *,vec,
1102 unsigned long, vlen, loff_t, pos) 1170 unsigned long, vlen, loff_t, pos)
1103{ 1171{
1104 return __compat_sys_preadv64(fd, vec, vlen, pos); 1172 return do_compat_preadv64(fd, vec, vlen, pos, 0);
1105} 1173}
1106#endif 1174#endif
1107 1175
@@ -1111,12 +1179,25 @@ COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
1111{ 1179{
1112 loff_t pos = ((loff_t)pos_high << 32) | pos_low; 1180 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1113 1181
1114 return __compat_sys_preadv64(fd, vec, vlen, pos); 1182 return do_compat_preadv64(fd, vec, vlen, pos, 0);
1183}
1184
1185COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd,
1186 const struct compat_iovec __user *,vec,
1187 compat_ulong_t, vlen, u32, pos_low, u32, pos_high,
1188 int, flags)
1189{
1190 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1191
1192 if (pos == -1)
1193 return do_compat_readv(fd, vec, vlen, flags);
1194
1195 return do_compat_preadv64(fd, vec, vlen, pos, flags);
1115} 1196}
1116 1197
1117static size_t compat_writev(struct file *file, 1198static size_t compat_writev(struct file *file,
1118 const struct compat_iovec __user *vec, 1199 const struct compat_iovec __user *vec,
1119 unsigned long vlen, loff_t *pos) 1200 unsigned long vlen, loff_t *pos, int flags)
1120{ 1201{
1121 ssize_t ret = -EBADF; 1202 ssize_t ret = -EBADF;
1122 1203
@@ -1127,7 +1208,7 @@ static size_t compat_writev(struct file *file,
1127 if (!(file->f_mode & FMODE_CAN_WRITE)) 1208 if (!(file->f_mode & FMODE_CAN_WRITE))
1128 goto out; 1209 goto out;
1129 1210
1130 ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos); 1211 ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos, 0);
1131 1212
1132out: 1213out:
1133 if (ret > 0) 1214 if (ret > 0)
@@ -1136,9 +1217,9 @@ out:
1136 return ret; 1217 return ret;
1137} 1218}
1138 1219
1139COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, 1220static size_t do_compat_writev(compat_ulong_t fd,
1140 const struct compat_iovec __user *, vec, 1221 const struct compat_iovec __user* vec,
1141 compat_ulong_t, vlen) 1222 compat_ulong_t vlen, int flags)
1142{ 1223{
1143 struct fd f = fdget_pos(fd); 1224 struct fd f = fdget_pos(fd);
1144 ssize_t ret; 1225 ssize_t ret;
@@ -1147,16 +1228,23 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
1147 if (!f.file) 1228 if (!f.file)
1148 return -EBADF; 1229 return -EBADF;
1149 pos = f.file->f_pos; 1230 pos = f.file->f_pos;
1150 ret = compat_writev(f.file, vec, vlen, &pos); 1231 ret = compat_writev(f.file, vec, vlen, &pos, flags);
1151 if (ret >= 0) 1232 if (ret >= 0)
1152 f.file->f_pos = pos; 1233 f.file->f_pos = pos;
1153 fdput_pos(f); 1234 fdput_pos(f);
1154 return ret; 1235 return ret;
1155} 1236}
1156 1237
1157static long __compat_sys_pwritev64(unsigned long fd, 1238COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
1239 const struct compat_iovec __user *, vec,
1240 compat_ulong_t, vlen)
1241{
1242 return do_compat_writev(fd, vec, vlen, 0);
1243}
1244
1245static long do_compat_pwritev64(unsigned long fd,
1158 const struct compat_iovec __user *vec, 1246 const struct compat_iovec __user *vec,
1159 unsigned long vlen, loff_t pos) 1247 unsigned long vlen, loff_t pos, int flags)
1160{ 1248{
1161 struct fd f; 1249 struct fd f;
1162 ssize_t ret; 1250 ssize_t ret;
@@ -1168,7 +1256,7 @@ static long __compat_sys_pwritev64(unsigned long fd,
1168 return -EBADF; 1256 return -EBADF;
1169 ret = -ESPIPE; 1257 ret = -ESPIPE;
1170 if (f.file->f_mode & FMODE_PWRITE) 1258 if (f.file->f_mode & FMODE_PWRITE)
1171 ret = compat_writev(f.file, vec, vlen, &pos); 1259 ret = compat_writev(f.file, vec, vlen, &pos, flags);
1172 fdput(f); 1260 fdput(f);
1173 return ret; 1261 return ret;
1174} 1262}
@@ -1178,7 +1266,7 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
1178 const struct compat_iovec __user *,vec, 1266 const struct compat_iovec __user *,vec,
1179 unsigned long, vlen, loff_t, pos) 1267 unsigned long, vlen, loff_t, pos)
1180{ 1268{
1181 return __compat_sys_pwritev64(fd, vec, vlen, pos); 1269 return do_compat_pwritev64(fd, vec, vlen, pos, 0);
1182} 1270}
1183#endif 1271#endif
1184 1272
@@ -1188,8 +1276,21 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
1188{ 1276{
1189 loff_t pos = ((loff_t)pos_high << 32) | pos_low; 1277 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1190 1278
1191 return __compat_sys_pwritev64(fd, vec, vlen, pos); 1279 return do_compat_pwritev64(fd, vec, vlen, pos, 0);
1280}
1281
1282COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd,
1283 const struct compat_iovec __user *,vec,
1284 compat_ulong_t, vlen, u32, pos_low, u32, pos_high, int, flags)
1285{
1286 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1287
1288 if (pos == -1)
1289 return do_compat_writev(fd, vec, vlen, flags);
1290
1291 return do_compat_pwritev64(fd, vec, vlen, pos, flags);
1192} 1292}
1293
1193#endif 1294#endif
1194 1295
1195static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, 1296static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,