diff options
author | Theodore Ts'o <tytso@mit.edu> | 2014-04-21 14:36:30 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-04-21 14:36:30 -0400 |
commit | 7ed07ba8c3e6160e0af3adc0f59561de154c4c2e (patch) | |
tree | cfd7a3b5e541ae9bddb1d8cf74d50fc26d2450e2 /fs/ext4/file.c | |
parent | 8ad2850f44831919f63f0e58d7203e65d5b3914c (diff) |
ext4: factor out common code in ext4_file_write()
This shouldn't change any logic flow; just delete duplicated code.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4/file.c')
-rw-r--r-- | fs/ext4/file.c | 56 |
1 files changed, 22 insertions, 34 deletions
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 20f1c03b6077..3736d9dfe325 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -97,8 +97,9 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
97 | { | 97 | { |
98 | struct file *file = iocb->ki_filp; | 98 | struct file *file = iocb->ki_filp; |
99 | struct inode *inode = file_inode(iocb->ki_filp); | 99 | struct inode *inode = file_inode(iocb->ki_filp); |
100 | struct mutex *aio_mutex = NULL; | ||
100 | struct blk_plug plug; | 101 | struct blk_plug plug; |
101 | int unaligned_aio = 0; | 102 | int o_direct = file->f_flags & O_DIRECT; |
102 | int overwrite = 0; | 103 | int overwrite = 0; |
103 | size_t length = iov_length(iov, nr_segs); | 104 | size_t length = iov_length(iov, nr_segs); |
104 | ssize_t ret; | 105 | ssize_t ret; |
@@ -123,15 +124,13 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
123 | } | 124 | } |
124 | } | 125 | } |
125 | 126 | ||
126 | if (unlikely(iocb->ki_filp->f_flags & O_DIRECT)) { | 127 | if (o_direct) { |
127 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && | ||
128 | !is_sync_kiocb(iocb)) | ||
129 | unaligned_aio = ext4_unaligned_aio(inode, iov, | ||
130 | nr_segs, pos); | ||
131 | |||
132 | /* Unaligned direct AIO must be serialized; see comment above */ | 128 | /* Unaligned direct AIO must be serialized; see comment above */ |
133 | if (unaligned_aio) { | 129 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && |
134 | mutex_lock(ext4_aio_mutex(inode)); | 130 | !is_sync_kiocb(iocb) && |
131 | ext4_unaligned_aio(inode, iov, nr_segs, pos)) { | ||
132 | aio_mutex = ext4_aio_mutex(inode); | ||
133 | mutex_lock(aio_mutex); | ||
135 | ext4_unwritten_wait(inode); | 134 | ext4_unwritten_wait(inode); |
136 | } | 135 | } |
137 | 136 | ||
@@ -141,7 +140,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
141 | iocb->private = &overwrite; | 140 | iocb->private = &overwrite; |
142 | 141 | ||
143 | /* check whether we do a DIO overwrite or not */ | 142 | /* check whether we do a DIO overwrite or not */ |
144 | if (ext4_should_dioread_nolock(inode) && !unaligned_aio && | 143 | if (ext4_should_dioread_nolock(inode) && !aio_mutex && |
145 | !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { | 144 | !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { |
146 | struct ext4_map_blocks map; | 145 | struct ext4_map_blocks map; |
147 | unsigned int blkbits = inode->i_blkbits; | 146 | unsigned int blkbits = inode->i_blkbits; |
@@ -168,35 +167,24 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
168 | if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) | 167 | if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) |
169 | overwrite = 1; | 168 | overwrite = 1; |
170 | } | 169 | } |
171 | 170 | } else | |
172 | ret = __generic_file_aio_write(iocb, iov, nr_segs); | ||
173 | mutex_unlock(&inode->i_mutex); | ||
174 | |||
175 | if (ret > 0) { | ||
176 | ssize_t err; | ||
177 | |||
178 | err = generic_write_sync(file, iocb->ki_pos - ret, ret); | ||
179 | if (err < 0) | ||
180 | ret = err; | ||
181 | } | ||
182 | blk_finish_plug(&plug); | ||
183 | |||
184 | if (unaligned_aio) | ||
185 | mutex_unlock(ext4_aio_mutex(inode)); | ||
186 | } else { | ||
187 | mutex_lock(&inode->i_mutex); | 171 | mutex_lock(&inode->i_mutex); |
188 | ret = __generic_file_aio_write(iocb, iov, nr_segs); | ||
189 | mutex_unlock(&inode->i_mutex); | ||
190 | 172 | ||
191 | if (ret > 0) { | 173 | ret = __generic_file_aio_write(iocb, iov, nr_segs); |
192 | ssize_t err; | 174 | mutex_unlock(&inode->i_mutex); |
193 | 175 | ||
194 | err = generic_write_sync(file, iocb->ki_pos - ret, ret); | 176 | if (ret > 0) { |
195 | if (err < 0) | 177 | ssize_t err; |
196 | ret = err; | 178 | |
197 | } | 179 | err = generic_write_sync(file, iocb->ki_pos - ret, ret); |
180 | if (err < 0) | ||
181 | ret = err; | ||
198 | } | 182 | } |
183 | if (o_direct) | ||
184 | blk_finish_plug(&plug); | ||
199 | 185 | ||
186 | if (aio_mutex) | ||
187 | mutex_unlock(aio_mutex); | ||
200 | return ret; | 188 | return ret; |
201 | } | 189 | } |
202 | 190 | ||