Skip to content

Commit ae2f33a

Browse files
Christoph Hellwigbrauner
authored andcommitted
iomap: factor out a iomap_dio_done helper
Split out the struct iomap-dio level final completion from iomap_dio_bio_end_io into a helper to clean up the code and make it reusable. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20250206064035.2323428-7-hch@lst.de Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 63b6691 commit ae2f33a

1 file changed

Lines changed: 38 additions & 38 deletions

File tree

fs/iomap/direct-io.c

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -165,43 +165,31 @@ static inline void iomap_dio_set_error(struct iomap_dio *dio, int ret)
165165
cmpxchg(&dio->error, 0, ret);
166166
}
167167

168-
void iomap_dio_bio_end_io(struct bio *bio)
168+
/*
169+
* Called when dio->ref reaches zero from an I/O completion.
170+
*/
171+
static void iomap_dio_done(struct iomap_dio *dio)
169172
{
170-
struct iomap_dio *dio = bio->bi_private;
171-
bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY);
172173
struct kiocb *iocb = dio->iocb;
173174

174-
if (bio->bi_status)
175-
iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status));
176-
if (!atomic_dec_and_test(&dio->ref))
177-
goto release_bio;
178-
179-
/*
180-
* Synchronous dio, task itself will handle any completion work
181-
* that needs after IO. All we need to do is wake the task.
182-
*/
183175
if (dio->wait_for_completion) {
176+
/*
177+
* Synchronous I/O, task itself will handle any completion work
178+
* that needs after IO. All we need to do is wake the task.
179+
*/
184180
struct task_struct *waiter = dio->submit.waiter;
185181

186182
WRITE_ONCE(dio->submit.waiter, NULL);
187183
blk_wake_io_task(waiter);
188-
goto release_bio;
189-
}
190-
191-
/*
192-
* Flagged with IOMAP_DIO_INLINE_COMP, we can complete it inline
193-
*/
194-
if (dio->flags & IOMAP_DIO_INLINE_COMP) {
184+
} else if (dio->flags & IOMAP_DIO_INLINE_COMP) {
195185
WRITE_ONCE(iocb->private, NULL);
196186
iomap_dio_complete_work(&dio->aio.work);
197-
goto release_bio;
198-
}
199-
200-
/*
201-
* If this dio is flagged with IOMAP_DIO_CALLER_COMP, then schedule
202-
* our completion that way to avoid an async punt to a workqueue.
203-
*/
204-
if (dio->flags & IOMAP_DIO_CALLER_COMP) {
187+
} else if (dio->flags & IOMAP_DIO_CALLER_COMP) {
188+
/*
189+
* If this dio is flagged with IOMAP_DIO_CALLER_COMP, then
190+
* schedule our completion that way to avoid an async punt to a
191+
* workqueue.
192+
*/
205193
/* only polled IO cares about private cleared */
206194
iocb->private = dio;
207195
iocb->dio_complete = iomap_dio_deferred_complete;
@@ -219,19 +207,31 @@ void iomap_dio_bio_end_io(struct bio *bio)
219207
* issuer.
220208
*/
221209
iocb->ki_complete(iocb, 0);
222-
goto release_bio;
210+
} else {
211+
struct inode *inode = file_inode(iocb->ki_filp);
212+
213+
/*
214+
* Async DIO completion that requires filesystem level
215+
* completion work gets punted to a work queue to complete as
216+
* the operation may require more IO to be issued to finalise
217+
* filesystem metadata changes or guarantee data integrity.
218+
*/
219+
INIT_WORK(&dio->aio.work, iomap_dio_complete_work);
220+
queue_work(inode->i_sb->s_dio_done_wq, &dio->aio.work);
223221
}
222+
}
223+
224+
void iomap_dio_bio_end_io(struct bio *bio)
225+
{
226+
struct iomap_dio *dio = bio->bi_private;
227+
bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY);
228+
229+
if (bio->bi_status)
230+
iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status));
231+
232+
if (atomic_dec_and_test(&dio->ref))
233+
iomap_dio_done(dio);
224234

225-
/*
226-
* Async DIO completion that requires filesystem level completion work
227-
* gets punted to a work queue to complete as the operation may require
228-
* more IO to be issued to finalise filesystem metadata changes or
229-
* guarantee data integrity.
230-
*/
231-
INIT_WORK(&dio->aio.work, iomap_dio_complete_work);
232-
queue_work(file_inode(iocb->ki_filp)->i_sb->s_dio_done_wq,
233-
&dio->aio.work);
234-
release_bio:
235235
if (should_dirty) {
236236
bio_check_pages_dirty(bio);
237237
} else {

0 commit comments

Comments
 (0)