diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9cc57c3b4661..bf545d017210 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -769,6 +769,60 @@ int ext4_get_block(struct inode *inode, sector_t iblock, | |||
769 | } | 769 | } |
770 | 770 | ||
771 | /* | 771 | /* |
772 | * Get block function used when preparing for buffered write if we require | ||
773 | * creating an unwritten extent if blocks haven't been allocated. The extent | ||
774 | * will be converted to written after the IO is complete. | ||
775 | */ | ||
776 | int ext4_get_block_unwritten(struct inode *inode, sector_t iblock, | ||
777 | struct buffer_head *bh_result, int create) | ||
778 | { | ||
779 | ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n", | ||
780 | inode->i_ino, create); | ||
781 | return _ext4_get_block(inode, iblock, bh_result, | ||
782 | EXT4_GET_BLOCKS_IO_CREATE_EXT); | ||
783 | } | ||
784 | |||
785 | /* Get block function for DIO reads and writes to inodes without extents */ | ||
786 | int ext4_dio_get_block(struct inode *inode, sector_t iblock, | ||
787 | struct buffer_head *bh, int create) | ||
788 | { | ||
789 | return _ext4_get_block(inode, iblock, bh, | ||
790 | create ? EXT4_GET_BLOCKS_CREATE : 0); | ||
791 | } | ||
792 | |||
793 | /* | ||
794 | * Get block function for DIO writes when we create unwritten extent if | ||
795 | * blocks are not allocated yet. The extent will be converted to written | ||
796 | * after IO is complete. | ||
797 | */ | ||
798 | static int ext4_dio_get_block_unwritten(struct inode *inode, sector_t iblock, | ||
799 | struct buffer_head *bh_result, int create) | ||
800 | { | ||
801 | ext4_debug("ext4_dio_get_block_unwritten: inode %lu, create flag %d\n", | ||
802 | inode->i_ino, create); | ||
803 | return _ext4_get_block(inode, iblock, bh_result, | ||
804 | EXT4_GET_BLOCKS_IO_CREATE_EXT); | ||
805 | } | ||
806 | |||
807 | static int ext4_dio_get_block_overwrite(struct inode *inode, sector_t iblock, | ||
808 | struct buffer_head *bh_result, int create) | ||
809 | { | ||
810 | int ret; | ||
811 | |||
812 | ext4_debug("ext4_dio_get_block_overwrite: inode %lu, create flag %d\n", | ||
813 | inode->i_ino, create); | ||
814 | ret = _ext4_get_block(inode, iblock, bh_result, 0); | ||
815 | /* | ||
816 | * Blocks should have been preallocated! ext4_file_write_iter() checks | ||
817 | * that. | ||
818 | */ | ||
819 | WARN_ON_ONCE(!buffer_mapped(bh_result)); | ||
820 | |||
821 | return ret; | ||
822 | } | ||
823 | |||
824 | |||
825 | /* | ||
772 | * `handle' can be NULL if create is zero | 826 | * `handle' can be NULL if create is zero |
773 | */ | 827 | */ |
774 | struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, | 828 | struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, |
@@ -1079,13 +1133,14 @@ retry_journal: | |||
1079 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | 1133 | #ifdef CONFIG_EXT4_FS_ENCRYPTION |
1080 | if (ext4_should_dioread_nolock(inode)) | 1134 | if (ext4_should_dioread_nolock(inode)) |
1081 | ret = ext4_block_write_begin(page, pos, len, | 1135 | ret = ext4_block_write_begin(page, pos, len, |
1082 | ext4_get_block_write); | 1136 | ext4_get_block_unwritten); |
1083 | else | 1137 | else |
1084 | ret = ext4_block_write_begin(page, pos, len, | 1138 | ret = ext4_block_write_begin(page, pos, len, |
1085 | ext4_get_block); | 1139 | ext4_get_block); |
1086 | #else | 1140 | #else |
1087 | if (ext4_should_dioread_nolock(inode)) | 1141 | if (ext4_should_dioread_nolock(inode)) |
1088 | ret = __block_write_begin(page, pos, len, ext4_get_block_write); | 1142 | ret = __block_write_begin(page, pos, len, |
1143 | ext4_get_block_unwritten); | ||
1089 | else | 1144 | else |
1090 | ret = __block_write_begin(page, pos, len, ext4_get_block); | 1145 | ret = __block_write_begin(page, pos, len, ext4_get_block); |
1091 | #endif | 1146 | #endif |
@@ -3084,37 +3139,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait) | |||
3084 | return try_to_free_buffers(page); | 3139 | return try_to_free_buffers(page); |
3085 | } | 3140 | } |
3086 | 3141 | ||
3087 | /* | ||
3088 | * ext4_get_block used when preparing for a DIO write or buffer write. | ||
3089 | * We allocate an uinitialized extent if blocks haven't been allocated. | ||
3090 | * The extent will be converted to initialized after the IO is complete. | ||
3091 | */ | ||
3092 | int ext4_get_block_write(struct inode *inode, sector_t iblock, | ||
3093 | struct buffer_head *bh_result, int create) | ||
3094 | { | ||
3095 | ext4_debug("ext4_get_block_write: inode %lu, create flag %d\n", | ||
3096 | inode->i_ino, create); | ||
3097 | return _ext4_get_block(inode, iblock, bh_result, | ||
3098 | EXT4_GET_BLOCKS_IO_CREATE_EXT); | ||
3099 | } | ||
3100 | |||
3101 | static int ext4_get_block_overwrite(struct inode *inode, sector_t iblock, | ||
3102 | struct buffer_head *bh_result, int create) | ||
3103 | { | ||
3104 | int ret; | ||
3105 | |||
3106 | ext4_debug("ext4_get_block_overwrite: inode %lu, create flag %d\n", | ||
3107 | inode->i_ino, create); | ||
3108 | ret = _ext4_get_block(inode, iblock, bh_result, 0); | ||
3109 | /* | ||
3110 | * Blocks should have been preallocated! ext4_file_write_iter() checks | ||
3111 | * that. | ||
3112 | */ | ||
3113 | WARN_ON_ONCE(!buffer_mapped(bh_result)); | ||
3114 | |||
3115 | return ret; | ||
3116 | } | ||
3117 | |||
3118 | #ifdef CONFIG_FS_DAX | 3142 | #ifdef CONFIG_FS_DAX |
3119 | int ext4_dax_mmap_get_block(struct inode *inode, sector_t iblock, | 3143 | int ext4_dax_mmap_get_block(struct inode *inode, sector_t iblock, |
3120 | struct buffer_head *bh_result, int create) | 3144 | struct buffer_head *bh_result, int create) |
@@ -3282,7 +3306,7 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
3282 | */ | 3306 | */ |
3283 | iocb->private = NULL; | 3307 | iocb->private = NULL; |
3284 | if (overwrite) { | 3308 | if (overwrite) { |
3285 | get_block_func = ext4_get_block_overwrite; | 3309 | get_block_func = ext4_dio_get_block_overwrite; |
3286 | } else { | 3310 | } else { |
3287 | ext4_inode_aio_set(inode, NULL); | 3311 | ext4_inode_aio_set(inode, NULL); |
3288 | if (!is_sync_kiocb(iocb)) { | 3312 | if (!is_sync_kiocb(iocb)) { |
@@ -3304,7 +3328,7 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
3304 | */ | 3328 | */ |
3305 | ext4_inode_aio_set(inode, io_end); | 3329 | ext4_inode_aio_set(inode, io_end); |
3306 | } | 3330 | } |
3307 | get_block_func = ext4_get_block_write; | 3331 | get_block_func = ext4_dio_get_block_unwritten; |
3308 | dio_flags = DIO_LOCKING; | 3332 | dio_flags = DIO_LOCKING; |
3309 | } | 3333 | } |
3310 | #ifdef CONFIG_EXT4_FS_ENCRYPTION | 3334 | #ifdef CONFIG_EXT4_FS_ENCRYPTION |
@@ -5498,7 +5522,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
5498 | unlock_page(page); | 5522 | unlock_page(page); |
5499 | /* OK, we need to fill the hole... */ | 5523 | /* OK, we need to fill the hole... */ |
5500 | if (ext4_should_dioread_nolock(inode)) | 5524 | if (ext4_should_dioread_nolock(inode)) |
5501 | get_block = ext4_get_block_write; | 5525 | get_block = ext4_get_block_unwritten; |
5502 | else | 5526 | else |
5503 | get_block = ext4_get_block; | 5527 | get_block = ext4_get_block; |
5504 | retry_alloc: | 5528 | retry_alloc: |