@@ -35,6 +35,7 @@ struct nfs_local_kiocb {
3535 struct bio_vec * bvec ;
3636 struct nfs_pgio_header * hdr ;
3737 struct work_struct work ;
38+ void (* aio_complete_work )(struct work_struct * );
3839 struct nfsd_file * localio ;
3940};
4041
@@ -48,6 +49,11 @@ struct nfs_local_fsync_ctx {
4849static bool localio_enabled __read_mostly = true;
4950module_param (localio_enabled , bool , 0644 );
5051
52+ static bool localio_O_DIRECT_semantics __read_mostly = false;
53+ module_param (localio_O_DIRECT_semantics , bool , 0644 );
54+ MODULE_PARM_DESC (localio_O_DIRECT_semantics ,
55+ "LOCALIO will use O_DIRECT semantics to filesystem." );
56+
5157static inline bool nfs_client_is_local (const struct nfs_client * clp )
5258{
5359 return !!test_bit (NFS_CS_LOCAL_IO , & clp -> cl_flags );
@@ -285,10 +291,19 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr,
285291 kfree (iocb );
286292 return NULL ;
287293 }
288- init_sync_kiocb (& iocb -> kiocb , file );
294+
295+ if (localio_O_DIRECT_semantics &&
296+ test_bit (NFS_IOHDR_ODIRECT , & hdr -> flags )) {
297+ iocb -> kiocb .ki_filp = file ;
298+ iocb -> kiocb .ki_flags = IOCB_DIRECT ;
299+ } else
300+ init_sync_kiocb (& iocb -> kiocb , file );
301+
289302 iocb -> kiocb .ki_pos = hdr -> args .offset ;
290303 iocb -> hdr = hdr ;
291304 iocb -> kiocb .ki_flags &= ~IOCB_APPEND ;
305+ iocb -> aio_complete_work = NULL ;
306+
292307 return iocb ;
293308}
294309
@@ -343,6 +358,18 @@ nfs_local_pgio_release(struct nfs_local_kiocb *iocb)
343358 nfs_local_hdr_release (hdr , hdr -> task .tk_ops );
344359}
345360
361+ /*
362+ * Complete the I/O from iocb->kiocb.ki_complete()
363+ *
364+ * Note that this function can be called from a bottom half context,
365+ * hence we need to queue the rpc_call_done() etc to a workqueue
366+ */
367+ static inline void nfs_local_pgio_aio_complete (struct nfs_local_kiocb * iocb )
368+ {
369+ INIT_WORK (& iocb -> work , iocb -> aio_complete_work );
370+ queue_work (nfsiod_workqueue , & iocb -> work );
371+ }
372+
346373static void
347374nfs_local_read_done (struct nfs_local_kiocb * iocb , long status )
348375{
@@ -365,6 +392,23 @@ nfs_local_read_done(struct nfs_local_kiocb *iocb, long status)
365392 status > 0 ? status : 0 , hdr -> res .eof );
366393}
367394
395+ static void nfs_local_read_aio_complete_work (struct work_struct * work )
396+ {
397+ struct nfs_local_kiocb * iocb =
398+ container_of (work , struct nfs_local_kiocb , work );
399+
400+ nfs_local_pgio_release (iocb );
401+ }
402+
403+ static void nfs_local_read_aio_complete (struct kiocb * kiocb , long ret )
404+ {
405+ struct nfs_local_kiocb * iocb =
406+ container_of (kiocb , struct nfs_local_kiocb , kiocb );
407+
408+ nfs_local_read_done (iocb , ret );
409+ nfs_local_pgio_aio_complete (iocb ); /* Calls nfs_local_read_aio_complete_work */
410+ }
411+
368412static void nfs_local_call_read (struct work_struct * work )
369413{
370414 struct nfs_local_kiocb * iocb =
@@ -379,10 +423,10 @@ static void nfs_local_call_read(struct work_struct *work)
379423 nfs_local_iter_init (& iter , iocb , READ );
380424
381425 status = filp -> f_op -> read_iter (& iocb -> kiocb , & iter );
382- WARN_ON_ONCE (status == - EIOCBQUEUED );
383-
384- nfs_local_read_done (iocb , status );
385- nfs_local_pgio_release ( iocb );
426+ if (status != - EIOCBQUEUED ) {
427+ nfs_local_read_done ( iocb , status );
428+ nfs_local_pgio_release (iocb );
429+ }
386430
387431 revert_creds (save_cred );
388432}
@@ -410,6 +454,11 @@ nfs_do_local_read(struct nfs_pgio_header *hdr,
410454 nfs_local_pgio_init (hdr , call_ops );
411455 hdr -> res .eof = false;
412456
457+ if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
458+ iocb -> kiocb .ki_complete = nfs_local_read_aio_complete ;
459+ iocb -> aio_complete_work = nfs_local_read_aio_complete_work ;
460+ }
461+
413462 INIT_WORK (& iocb -> work , nfs_local_call_read );
414463 queue_work (nfslocaliod_workqueue , & iocb -> work );
415464
@@ -534,6 +583,24 @@ nfs_local_write_done(struct nfs_local_kiocb *iocb, long status)
534583 nfs_local_pgio_done (hdr , status );
535584}
536585
586+ static void nfs_local_write_aio_complete_work (struct work_struct * work )
587+ {
588+ struct nfs_local_kiocb * iocb =
589+ container_of (work , struct nfs_local_kiocb , work );
590+
591+ nfs_local_vfs_getattr (iocb );
592+ nfs_local_pgio_release (iocb );
593+ }
594+
595+ static void nfs_local_write_aio_complete (struct kiocb * kiocb , long ret )
596+ {
597+ struct nfs_local_kiocb * iocb =
598+ container_of (kiocb , struct nfs_local_kiocb , kiocb );
599+
600+ nfs_local_write_done (iocb , ret );
601+ nfs_local_pgio_aio_complete (iocb ); /* Calls nfs_local_write_aio_complete_work */
602+ }
603+
537604static void nfs_local_call_write (struct work_struct * work )
538605{
539606 struct nfs_local_kiocb * iocb =
@@ -552,11 +619,11 @@ static void nfs_local_call_write(struct work_struct *work)
552619 file_start_write (filp );
553620 status = filp -> f_op -> write_iter (& iocb -> kiocb , & iter );
554621 file_end_write (filp );
555- WARN_ON_ONCE (status == - EIOCBQUEUED );
556-
557- nfs_local_write_done (iocb , status );
558- nfs_local_vfs_getattr (iocb );
559- nfs_local_pgio_release ( iocb );
622+ if (status != - EIOCBQUEUED ) {
623+ nfs_local_write_done ( iocb , status );
624+ nfs_local_vfs_getattr (iocb );
625+ nfs_local_pgio_release (iocb );
626+ }
560627
561628 revert_creds (save_cred );
562629 current -> flags = old_flags ;
@@ -592,10 +659,16 @@ nfs_do_local_write(struct nfs_pgio_header *hdr,
592659 case NFS_FILE_SYNC :
593660 iocb -> kiocb .ki_flags |= IOCB_DSYNC |IOCB_SYNC ;
594661 }
662+
595663 nfs_local_pgio_init (hdr , call_ops );
596664
597665 nfs_set_local_verifier (hdr -> inode , hdr -> res .verf , hdr -> args .stable );
598666
667+ if (iocb -> kiocb .ki_flags & IOCB_DIRECT ) {
668+ iocb -> kiocb .ki_complete = nfs_local_write_aio_complete ;
669+ iocb -> aio_complete_work = nfs_local_write_aio_complete_work ;
670+ }
671+
599672 INIT_WORK (& iocb -> work , nfs_local_call_write );
600673 queue_work (nfslocaliod_workqueue , & iocb -> work );
601674
0 commit comments