@@ -714,50 +714,26 @@ static void ext4_update_bh_state(struct buffer_head *bh, unsigned long flags)
714714 cmpxchg (& bh -> b_state , old_state , new_state ) != old_state ));
715715}
716716
717- /* Maximum number of blocks we map for direct IO at once. */
718- #define DIO_MAX_BLOCKS 4096
719-
720717static int _ext4_get_block (struct inode * inode , sector_t iblock ,
721718 struct buffer_head * bh , int flags )
722719{
723- handle_t * handle = ext4_journal_current_handle ();
724720 struct ext4_map_blocks map ;
725- int ret = 0 , started = 0 ;
726- int dio_credits ;
721+ int ret = 0 ;
727722
728723 if (ext4_has_inline_data (inode ))
729724 return - ERANGE ;
730725
731726 map .m_lblk = iblock ;
732727 map .m_len = bh -> b_size >> inode -> i_blkbits ;
733728
734- if (flags && !handle ) {
735- /* Direct IO write... */
736- if (map .m_len > DIO_MAX_BLOCKS )
737- map .m_len = DIO_MAX_BLOCKS ;
738- dio_credits = ext4_chunk_trans_blocks (inode , map .m_len );
739- handle = ext4_journal_start (inode , EXT4_HT_MAP_BLOCKS ,
740- dio_credits );
741- if (IS_ERR (handle )) {
742- ret = PTR_ERR (handle );
743- return ret ;
744- }
745- started = 1 ;
746- }
747-
748- ret = ext4_map_blocks (handle , inode , & map , flags );
729+ ret = ext4_map_blocks (ext4_journal_current_handle (), inode , & map ,
730+ flags );
749731 if (ret > 0 ) {
750- ext4_io_end_t * io_end = ext4_inode_aio (inode );
751-
752732 map_bh (bh , inode -> i_sb , map .m_pblk );
753733 ext4_update_bh_state (bh , map .m_flags );
754- if (io_end && io_end -> flag & EXT4_IO_END_UNWRITTEN )
755- set_buffer_defer_completion (bh );
756734 bh -> b_size = inode -> i_sb -> s_blocksize * map .m_len ;
757735 ret = 0 ;
758736 }
759- if (started )
760- ext4_journal_stop (handle );
761737 return ret ;
762738}
763739
@@ -782,12 +758,42 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
782758 EXT4_GET_BLOCKS_IO_CREATE_EXT );
783759}
784760
761+ /* Maximum number of blocks we map for direct IO at once. */
762+ #define DIO_MAX_BLOCKS 4096
763+
764+ static handle_t * start_dio_trans (struct inode * inode ,
765+ struct buffer_head * bh_result )
766+ {
767+ int dio_credits ;
768+
769+ /* Trim mapping request to maximum we can map at once for DIO */
770+ if (bh_result -> b_size >> inode -> i_blkbits > DIO_MAX_BLOCKS )
771+ bh_result -> b_size = DIO_MAX_BLOCKS << inode -> i_blkbits ;
772+ dio_credits = ext4_chunk_trans_blocks (inode ,
773+ bh_result -> b_size >> inode -> i_blkbits );
774+ return ext4_journal_start (inode , EXT4_HT_MAP_BLOCKS , dio_credits );
775+ }
776+
785777/* Get block function for DIO reads and writes to inodes without extents */
786778int ext4_dio_get_block (struct inode * inode , sector_t iblock ,
787779 struct buffer_head * bh , int create )
788780{
789- return _ext4_get_block (inode , iblock , bh ,
790- create ? EXT4_GET_BLOCKS_CREATE : 0 );
781+ handle_t * handle ;
782+ int ret ;
783+
784+ /* We don't expect handle for direct IO */
785+ WARN_ON_ONCE (ext4_journal_current_handle ());
786+
787+ if (create ) {
788+ handle = start_dio_trans (inode , bh );
789+ if (IS_ERR (handle ))
790+ return PTR_ERR (handle );
791+ }
792+ ret = _ext4_get_block (inode , iblock , bh ,
793+ create ? EXT4_GET_BLOCKS_CREATE : 0 );
794+ if (create )
795+ ext4_journal_stop (handle );
796+ return ret ;
791797}
792798
793799/*
@@ -798,10 +804,28 @@ int ext4_dio_get_block(struct inode *inode, sector_t iblock,
798804static int ext4_dio_get_block_unwritten (struct inode * inode , sector_t iblock ,
799805 struct buffer_head * bh_result , int create )
800806{
807+ handle_t * handle ;
808+ int ret ;
809+
801810 ext4_debug ("ext4_dio_get_block_unwritten: inode %lu, create flag %d\n" ,
802811 inode -> i_ino , create );
803- return _ext4_get_block (inode , iblock , bh_result ,
804- EXT4_GET_BLOCKS_IO_CREATE_EXT );
812+ /* We don't expect handle for direct IO */
813+ WARN_ON_ONCE (ext4_journal_current_handle ());
814+
815+ handle = start_dio_trans (inode , bh_result );
816+ if (IS_ERR (handle ))
817+ return PTR_ERR (handle );
818+ ret = _ext4_get_block (inode , iblock , bh_result ,
819+ EXT4_GET_BLOCKS_IO_CREATE_EXT );
820+ ext4_journal_stop (handle );
821+ if (!ret && buffer_unwritten (bh_result )) {
822+ ext4_io_end_t * io_end = ext4_inode_aio (inode );
823+
824+ set_buffer_defer_completion (bh_result );
825+ WARN_ON_ONCE (io_end && !(io_end -> flag & EXT4_IO_END_UNWRITTEN ));
826+ }
827+
828+ return ret ;
805829}
806830
807831static int ext4_dio_get_block_overwrite (struct inode * inode , sector_t iblock ,
@@ -811,12 +835,15 @@ static int ext4_dio_get_block_overwrite(struct inode *inode, sector_t iblock,
811835
812836 ext4_debug ("ext4_dio_get_block_overwrite: inode %lu, create flag %d\n" ,
813837 inode -> i_ino , create );
838+ /* We don't expect handle for direct IO */
839+ WARN_ON_ONCE (ext4_journal_current_handle ());
840+
814841 ret = _ext4_get_block (inode , iblock , bh_result , 0 );
815842 /*
816843 * Blocks should have been preallocated! ext4_file_write_iter() checks
817844 * that.
818845 */
819- WARN_ON_ONCE (!buffer_mapped (bh_result ));
846+ WARN_ON_ONCE (!buffer_mapped (bh_result ) || buffer_unwritten ( bh_result ) );
820847
821848 return ret ;
822849}
0 commit comments