1 ext4: factor out checks from ext4_file_write_iter()
3 From: Jan Kara <jack@suse.cz>
5 Factor out checks of 'from' and whether we are overwriting out of
6 ext4_file_write_iter() so that the function is easier to follow.
8 Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com>
9 Signed-off-by: Jan Kara <jack@suse.cz>
10 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 fs/ext4/file.c | 97 ++++++++++++++++++++++++++++++----------------------------
13 1 file changed, 50 insertions(+), 47 deletions(-)
15 diff --git a/fs/ext4/file.c b/fs/ext4/file.c
16 index 2a822d30e73f..9facb4dc5c70 100644
19 @@ -88,6 +88,51 @@ ext4_unaligned_aio(struct inode *inode, struct iov_iter *from, loff_t pos)
23 +/* Is IO overwriting allocated and initialized blocks? */
24 +static bool ext4_overwrite_io(struct inode *inode, loff_t pos, loff_t len)
26 + struct ext4_map_blocks map;
27 + unsigned int blkbits = inode->i_blkbits;
30 + if (pos + len > i_size_read(inode))
33 + map.m_lblk = pos >> blkbits;
34 + map.m_len = EXT4_MAX_BLOCKS(len, pos, blkbits);
37 + err = ext4_map_blocks(NULL, inode, &map, 0);
39 + * 'err==len' means that all of the blocks have been preallocated,
40 + * regardless of whether they have been initialized or not. To exclude
41 + * unwritten extents, we need to check m_flags.
43 + return err == blklen && (map.m_flags & EXT4_MAP_MAPPED);
46 +static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *from)
48 + struct inode *inode = file_inode(iocb->ki_filp);
51 + ret = generic_write_checks(iocb, from);
55 + * If we have encountered a bitmap-format file, the size limit
56 + * is smaller than s_maxbytes, which is for extent-mapped files.
58 + if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
59 + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
61 + if (iocb->ki_pos >= sbi->s_bitmap_maxbytes)
63 + iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos);
65 + return iov_iter_count(from);
69 ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
71 @@ -98,7 +143,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
75 - ret = generic_write_checks(iocb, from);
76 + ret = ext4_write_checks(iocb, from);
80 @@ -114,53 +159,11 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
81 ext4_unwritten_wait(inode);
85 - * If we have encountered a bitmap-format file, the size limit
86 - * is smaller than s_maxbytes, which is for extent-mapped files.
88 - if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
89 - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
91 - if (iocb->ki_pos >= sbi->s_bitmap_maxbytes) {
95 - iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos);
98 iocb->private = &overwrite;
100 - size_t length = iov_iter_count(from);
101 - loff_t pos = iocb->ki_pos;
103 - /* check whether we do a DIO overwrite or not */
104 - if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
105 - pos + length <= i_size_read(inode)) {
106 - struct ext4_map_blocks map;
107 - unsigned int blkbits = inode->i_blkbits;
110 - map.m_lblk = pos >> blkbits;
111 - map.m_len = EXT4_MAX_BLOCKS(length, pos, blkbits);
114 - err = ext4_map_blocks(NULL, inode, &map, 0);
116 - * 'err==len' means that all of blocks has
117 - * been preallocated no matter they are
118 - * initialized or not. For excluding
119 - * unwritten extents, we need to check
120 - * m_flags. There are two conditions that
121 - * indicate for initialized extents. 1) If we
122 - * hit extent cache, EXT4_MAP_MAPPED flag is
123 - * returned; 2) If we do a real lookup,
124 - * non-flags are returned. So we should check
125 - * these two conditions.
127 - if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
131 + /* Check whether we do a DIO overwrite or not */
132 + if (o_direct && ext4_should_dioread_nolock(inode) && !unaligned_aio &&
133 + ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from)))
136 ret = __generic_file_write_iter(iocb, from);