@@ -1036,6 +1036,50 @@ __be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp,
1036
1036
return nfsd_finish_read (rqstp , fhp , file , offset , count , eof , host_err );
1037
1037
}
1038
1038
1039
+ /**
1040
+ * nfsd_iter_read - Perform a VFS read using an iterator
1041
+ * @rqstp: RPC transaction context
1042
+ * @fhp: file handle of file to be read
1043
+ * @file: opened struct file of file to be read
1044
+ * @offset: starting byte offset
1045
+ * @count: IN: requested number of bytes; OUT: number of bytes read
1046
+ * @base: offset in first page of read buffer
1047
+ * @eof: OUT: set non-zero if operation reached the end of the file
1048
+ *
1049
+ * Some filesystems or situations cannot use nfsd_splice_read. This
1050
+ * function is the slightly less-performant fallback for those cases.
1051
+ *
1052
+ * Returns nfs_ok on success, otherwise an nfserr stat value is
1053
+ * returned.
1054
+ */
1055
+ __be32 nfsd_iter_read (struct svc_rqst * rqstp , struct svc_fh * fhp ,
1056
+ struct file * file , loff_t offset , unsigned long * count ,
1057
+ unsigned int base , u32 * eof )
1058
+ {
1059
+ unsigned long v , total ;
1060
+ struct iov_iter iter ;
1061
+ loff_t ppos = offset ;
1062
+ struct page * page ;
1063
+ ssize_t host_err ;
1064
+
1065
+ v = 0 ;
1066
+ total = * count ;
1067
+ while (total ) {
1068
+ page = * (rqstp -> rq_next_page ++ );
1069
+ rqstp -> rq_vec [v ].iov_base = page_address (page ) + base ;
1070
+ rqstp -> rq_vec [v ].iov_len = min_t (size_t , total , PAGE_SIZE - base );
1071
+ total -= rqstp -> rq_vec [v ].iov_len ;
1072
+ ++ v ;
1073
+ base = 0 ;
1074
+ }
1075
+ WARN_ON_ONCE (v > ARRAY_SIZE (rqstp -> rq_vec ));
1076
+
1077
+ trace_nfsd_read_vector (rqstp , fhp , offset , * count );
1078
+ iov_iter_kvec (& iter , ITER_DEST , rqstp -> rq_vec , v , * count );
1079
+ host_err = vfs_iter_read (file , & iter , & ppos , 0 );
1080
+ return nfsd_finish_read (rqstp , fhp , file , offset , count , eof , host_err );
1081
+ }
1082
+
1039
1083
/*
1040
1084
* Gathered writes: If another process is currently writing to the file,
1041
1085
* there's a high chance this is another nfsd (triggered by a bulk write
@@ -1161,14 +1205,24 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
1161
1205
return nfserr ;
1162
1206
}
1163
1207
1164
- /*
1165
- * Read data from a file. count must contain the requested read count
1166
- * on entry. On return, *count contains the number of bytes actually read.
1208
+ /**
1209
+ * nfsd_read - Read data from a file
1210
+ * @rqstp: RPC transaction context
1211
+ * @fhp: file handle of file to be read
1212
+ * @offset: starting byte offset
1213
+ * @count: IN: requested number of bytes; OUT: number of bytes read
1214
+ * @eof: OUT: set non-zero if operation reached the end of the file
1215
+ *
1216
+ * The caller must verify that there is enough space in @rqstp.rq_res
1217
+ * to perform this operation.
1218
+ *
1167
1219
* N.B. After this call fhp needs an fh_put
1220
+ *
1221
+ * Returns nfs_ok on success, otherwise an nfserr stat value is
1222
+ * returned.
1168
1223
*/
1169
1224
__be32 nfsd_read (struct svc_rqst * rqstp , struct svc_fh * fhp ,
1170
- loff_t offset , struct kvec * vec , int vlen , unsigned long * count ,
1171
- u32 * eof )
1225
+ loff_t offset , unsigned long * count , u32 * eof )
1172
1226
{
1173
1227
struct nfsd_file * nf ;
1174
1228
struct file * file ;
@@ -1183,12 +1237,10 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
1183
1237
if (file -> f_op -> splice_read && test_bit (RQ_SPLICE_OK , & rqstp -> rq_flags ))
1184
1238
err = nfsd_splice_read (rqstp , fhp , file , offset , count , eof );
1185
1239
else
1186
- err = nfsd_readv (rqstp , fhp , file , offset , vec , vlen , count , eof );
1240
+ err = nfsd_iter_read (rqstp , fhp , file , offset , count , 0 , eof );
1187
1241
1188
1242
nfsd_file_put (nf );
1189
-
1190
1243
trace_nfsd_read_done (rqstp , fhp , offset , * count );
1191
-
1192
1244
return err ;
1193
1245
}
1194
1246
0 commit comments