@@ -36,6 +36,7 @@ struct nfs_local_kiocb {
3636 struct nfs_pgio_header * hdr ;
3737 struct work_struct work ;
3838 void (* aio_complete_work )(struct work_struct * );
39+ struct iov_iter iter ____cacheline_aligned ;
3940 struct nfsd_file * localio ;
4041};
4142
@@ -411,13 +412,19 @@ nfs_local_pgio_done(struct nfs_pgio_header *hdr, long status)
411412 }
412413}
413414
415+ static void
416+ nfs_local_iocb_release (struct nfs_local_kiocb * iocb )
417+ {
418+ nfs_local_file_put (iocb -> localio );
419+ nfs_local_iocb_free (iocb );
420+ }
421+
414422static void
415423nfs_local_pgio_release (struct nfs_local_kiocb * iocb )
416424{
417425 struct nfs_pgio_header * hdr = iocb -> hdr ;
418426
419- nfs_local_file_put (iocb -> localio );
420- nfs_local_iocb_free (iocb );
427+ nfs_local_iocb_release (iocb );
421428 nfs_local_hdr_release (hdr , hdr -> task .tk_ops );
422429}
423430
@@ -483,18 +490,16 @@ static void nfs_local_call_read(struct work_struct *work)
483490 container_of (work , struct nfs_local_kiocb , work );
484491 struct file * filp = iocb -> kiocb .ki_filp ;
485492 const struct cred * save_cred ;
486- struct iov_iter iter ;
487493 ssize_t status ;
488494
489495 save_cred = override_creds (filp -> f_cred );
490496
491- nfs_local_iter_init (& iter , iocb , ITER_DEST );
492497 if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
493498 iocb -> kiocb .ki_complete = nfs_local_read_aio_complete ;
494499 iocb -> aio_complete_work = nfs_local_read_aio_complete_work ;
495500 }
496501
497- status = filp -> f_op -> read_iter (& iocb -> kiocb , & iter );
502+ status = filp -> f_op -> read_iter (& iocb -> kiocb , & iocb -> iter );
498503
499504 revert_creds (save_cred );
500505
@@ -505,25 +510,14 @@ static void nfs_local_call_read(struct work_struct *work)
505510}
506511
507512static int
508- nfs_do_local_read (struct nfs_pgio_header * hdr ,
509- struct nfsd_file * localio ,
513+ nfs_local_do_read (struct nfs_local_kiocb * iocb ,
510514 const struct rpc_call_ops * call_ops )
511515{
512- struct nfs_local_kiocb * iocb ;
513- struct file * file = nfs_to -> nfsd_file_file (localio );
514-
515- /* Don't support filesystems without read_iter */
516- if (!file -> f_op -> read_iter )
517- return - EAGAIN ;
516+ struct nfs_pgio_header * hdr = iocb -> hdr ;
518517
519518 dprintk ("%s: vfs_read count=%u pos=%llu\n" ,
520519 __func__ , hdr -> args .count , hdr -> args .offset );
521520
522- iocb = nfs_local_iocb_alloc (hdr , file , GFP_KERNEL );
523- if (iocb == NULL )
524- return - ENOMEM ;
525- iocb -> localio = localio ;
526-
527521 nfs_local_pgio_init (hdr , call_ops );
528522 hdr -> res .eof = false;
529523
@@ -680,20 +674,18 @@ static void nfs_local_call_write(struct work_struct *work)
680674 struct file * filp = iocb -> kiocb .ki_filp ;
681675 unsigned long old_flags = current -> flags ;
682676 const struct cred * save_cred ;
683- struct iov_iter iter ;
684677 ssize_t status ;
685678
686679 current -> flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO ;
687680 save_cred = override_creds (filp -> f_cred );
688681
689- nfs_local_iter_init (& iter , iocb , ITER_SOURCE );
690682 if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
691683 iocb -> kiocb .ki_complete = nfs_local_write_aio_complete ;
692684 iocb -> aio_complete_work = nfs_local_write_aio_complete_work ;
693685 }
694686
695687 file_start_write (filp );
696- status = filp -> f_op -> write_iter (& iocb -> kiocb , & iter );
688+ status = filp -> f_op -> write_iter (& iocb -> kiocb , & iocb -> iter );
697689 file_end_write (filp );
698690
699691 revert_creds (save_cred );
@@ -707,26 +699,15 @@ static void nfs_local_call_write(struct work_struct *work)
707699}
708700
709701static int
710- nfs_do_local_write (struct nfs_pgio_header * hdr ,
711- struct nfsd_file * localio ,
702+ nfs_local_do_write (struct nfs_local_kiocb * iocb ,
712703 const struct rpc_call_ops * call_ops )
713704{
714- struct nfs_local_kiocb * iocb ;
715- struct file * file = nfs_to -> nfsd_file_file (localio );
716-
717- /* Don't support filesystems without write_iter */
718- if (!file -> f_op -> write_iter )
719- return - EAGAIN ;
705+ struct nfs_pgio_header * hdr = iocb -> hdr ;
720706
721707 dprintk ("%s: vfs_write count=%u pos=%llu %s\n" ,
722708 __func__ , hdr -> args .count , hdr -> args .offset ,
723709 (hdr -> args .stable == NFS_UNSTABLE ) ? "unstable" : "stable" );
724710
725- iocb = nfs_local_iocb_alloc (hdr , file , GFP_NOIO );
726- if (iocb == NULL )
727- return - ENOMEM ;
728- iocb -> localio = localio ;
729-
730711 switch (hdr -> args .stable ) {
731712 default :
732713 break ;
@@ -747,32 +728,68 @@ nfs_do_local_write(struct nfs_pgio_header *hdr,
747728 return 0 ;
748729}
749730
731+ static struct nfs_local_kiocb *
732+ nfs_local_iocb_init (struct nfs_pgio_header * hdr , struct nfsd_file * localio )
733+ {
734+ struct file * file = nfs_to -> nfsd_file_file (localio );
735+ struct nfs_local_kiocb * iocb ;
736+ gfp_t gfp_mask ;
737+ int rw ;
738+
739+ if (hdr -> rw_mode & FMODE_READ ) {
740+ if (!file -> f_op -> read_iter )
741+ return ERR_PTR (- EOPNOTSUPP );
742+ gfp_mask = GFP_KERNEL ;
743+ rw = ITER_DEST ;
744+ } else {
745+ if (!file -> f_op -> write_iter )
746+ return ERR_PTR (- EOPNOTSUPP );
747+ gfp_mask = GFP_NOIO ;
748+ rw = ITER_SOURCE ;
749+ }
750+
751+ iocb = nfs_local_iocb_alloc (hdr , file , gfp_mask );
752+ if (iocb == NULL )
753+ return ERR_PTR (- ENOMEM );
754+ iocb -> hdr = hdr ;
755+ iocb -> localio = localio ;
756+
757+ nfs_local_iter_init (& iocb -> iter , iocb , rw );
758+
759+ return iocb ;
760+ }
761+
750762int nfs_local_doio (struct nfs_client * clp , struct nfsd_file * localio ,
751763 struct nfs_pgio_header * hdr ,
752764 const struct rpc_call_ops * call_ops )
753765{
766+ struct nfs_local_kiocb * iocb ;
754767 int status = 0 ;
755768
756769 if (!hdr -> args .count )
757770 return 0 ;
758771
772+ iocb = nfs_local_iocb_init (hdr , localio );
773+ if (IS_ERR (iocb ))
774+ return PTR_ERR (iocb );
775+
759776 switch (hdr -> rw_mode ) {
760777 case FMODE_READ :
761- status = nfs_do_local_read ( hdr , localio , call_ops );
778+ status = nfs_local_do_read ( iocb , call_ops );
762779 break ;
763780 case FMODE_WRITE :
764- status = nfs_do_local_write ( hdr , localio , call_ops );
781+ status = nfs_local_do_write ( iocb , call_ops );
765782 break ;
766783 default :
767784 dprintk ("%s: invalid mode: %d\n" , __func__ ,
768785 hdr -> rw_mode );
769- status = - EINVAL ;
786+ status = - EOPNOTSUPP ;
770787 }
771788
772789 if (status != 0 ) {
773790 if (status == - EAGAIN )
774791 nfs_localio_disable_client (clp );
775- nfs_local_file_put ( localio );
792+ nfs_local_iocb_release ( iocb );
776793 hdr -> task .tk_status = status ;
777794 nfs_local_hdr_release (hdr , call_ops );
778795 }
0 commit comments