@@ -277,23 +277,6 @@ nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred,
277277}
278278EXPORT_SYMBOL_GPL (nfs_local_open_fh );
279279
280- static struct bio_vec *
281- nfs_bvec_alloc_and_import_pagevec (struct page * * pagevec ,
282- unsigned int npages , gfp_t flags )
283- {
284- struct bio_vec * bvec , * p ;
285-
286- bvec = kmalloc_array (npages , sizeof (* bvec ), flags );
287- if (bvec != NULL ) {
288- for (p = bvec ; npages > 0 ; p ++ , pagevec ++ , npages -- ) {
289- p -> bv_page = * pagevec ;
290- p -> bv_len = PAGE_SIZE ;
291- p -> bv_offset = 0 ;
292- }
293- }
294- return bvec ;
295- }
296-
297280static void
298281nfs_local_iocb_free (struct nfs_local_kiocb * iocb )
299282{
@@ -310,8 +293,9 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr,
310293 iocb = kmalloc (sizeof (* iocb ), flags );
311294 if (iocb == NULL )
312295 return NULL ;
313- iocb -> bvec = nfs_bvec_alloc_and_import_pagevec (hdr -> page_array .pagevec ,
314- hdr -> page_array .npages , flags );
296+
297+ iocb -> bvec = kmalloc_array (hdr -> page_array .npages ,
298+ sizeof (struct bio_vec ), flags );
315299 if (iocb -> bvec == NULL ) {
316300 kfree (iocb );
317301 return NULL ;
@@ -354,22 +338,36 @@ static bool nfs_iov_iter_aligned_bvec(const struct iov_iter *i,
354338}
355339
356340static void
357- nfs_local_iter_init (struct iov_iter * i , struct nfs_local_kiocb * iocb , int dir )
341+ nfs_local_iter_init (struct iov_iter * i , struct nfs_local_kiocb * iocb , int rw )
358342{
359343 struct nfs_pgio_header * hdr = iocb -> hdr ;
344+ struct page * * pagevec = hdr -> page_array .pagevec ;
345+ unsigned long v , total ;
346+ unsigned int base ;
347+ size_t len ;
348+
349+ v = 0 ;
350+ total = hdr -> args .count ;
351+ base = hdr -> args .pgbase ;
352+ while (total && v < hdr -> page_array .npages ) {
353+ len = min_t (size_t , total , PAGE_SIZE - base );
354+ bvec_set_page (& iocb -> bvec [v ], * pagevec , len , base );
355+ total -= len ;
356+ ++ pagevec ;
357+ ++ v ;
358+ base = 0 ;
359+ }
360+ len = hdr -> args .count - total ;
360361
361- iov_iter_bvec (i , dir , iocb -> bvec , hdr -> page_array .npages ,
362- hdr -> args .count + hdr -> args .pgbase );
363- if (hdr -> args .pgbase != 0 )
364- iov_iter_advance (i , hdr -> args .pgbase );
362+ iov_iter_bvec (i , rw , iocb -> bvec , v , len );
365363
366364 if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
367365 u32 nf_dio_mem_align , nf_dio_offset_align , nf_dio_read_offset_align ;
368366 /* Verify the IO is DIO-aligned as required */
369367 nfs_to -> nfsd_file_dio_alignment (iocb -> localio , & nf_dio_mem_align ,
370368 & nf_dio_offset_align ,
371369 & nf_dio_read_offset_align );
372- if (dir == READ )
370+ if (rw == ITER_DEST )
373371 nf_dio_offset_align = nf_dio_read_offset_align ;
374372
375373 if (nf_dio_mem_align && nf_dio_offset_align &&
@@ -490,7 +488,11 @@ static void nfs_local_call_read(struct work_struct *work)
490488
491489 save_cred = override_creds (filp -> f_cred );
492490
493- nfs_local_iter_init (& iter , iocb , READ );
491+ nfs_local_iter_init (& iter , iocb , ITER_DEST );
492+ if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
493+ iocb -> kiocb .ki_complete = nfs_local_read_aio_complete ;
494+ iocb -> aio_complete_work = nfs_local_read_aio_complete_work ;
495+ }
494496
495497 status = filp -> f_op -> read_iter (& iocb -> kiocb , & iter );
496498
@@ -525,11 +527,6 @@ nfs_do_local_read(struct nfs_pgio_header *hdr,
525527 nfs_local_pgio_init (hdr , call_ops );
526528 hdr -> res .eof = false;
527529
528- if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
529- iocb -> kiocb .ki_complete = nfs_local_read_aio_complete ;
530- iocb -> aio_complete_work = nfs_local_read_aio_complete_work ;
531- }
532-
533530 INIT_WORK (& iocb -> work , nfs_local_call_read );
534531 queue_work (nfslocaliod_workqueue , & iocb -> work );
535532
@@ -689,7 +686,11 @@ static void nfs_local_call_write(struct work_struct *work)
689686 current -> flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO ;
690687 save_cred = override_creds (filp -> f_cred );
691688
692- nfs_local_iter_init (& iter , iocb , WRITE );
689+ nfs_local_iter_init (& iter , iocb , ITER_SOURCE );
690+ if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
691+ iocb -> kiocb .ki_complete = nfs_local_write_aio_complete ;
692+ iocb -> aio_complete_work = nfs_local_write_aio_complete_work ;
693+ }
693694
694695 file_start_write (filp );
695696 status = filp -> f_op -> write_iter (& iocb -> kiocb , & iter );
@@ -740,11 +741,6 @@ nfs_do_local_write(struct nfs_pgio_header *hdr,
740741
741742 nfs_set_local_verifier (hdr -> inode , hdr -> res .verf , hdr -> args .stable );
742743
743- if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
744- iocb -> kiocb .ki_complete = nfs_local_write_aio_complete ;
745- iocb -> aio_complete_work = nfs_local_write_aio_complete_work ;
746- }
747-
748744 INIT_WORK (& iocb -> work , nfs_local_call_write );
749745 queue_work (nfslocaliod_workqueue , & iocb -> work );
750746
0 commit comments