diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/page-io.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 48786cdb5e6c..d63cc5e9d3b5 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -308,6 +308,7 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end) | |||
308 | return io_end; | 308 | return io_end; |
309 | } | 309 | } |
310 | 310 | ||
311 | /* BIO completion function for page writeback */ | ||
311 | static void ext4_end_bio(struct bio *bio, int error) | 312 | static void ext4_end_bio(struct bio *bio, int error) |
312 | { | 313 | { |
313 | ext4_io_end_t *io_end = bio->bi_private; | 314 | ext4_io_end_t *io_end = bio->bi_private; |
@@ -318,18 +319,6 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
318 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) | 319 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) |
319 | error = 0; | 320 | error = 0; |
320 | 321 | ||
321 | if (io_end->flag & EXT4_IO_END_UNWRITTEN) { | ||
322 | /* | ||
323 | * Link bio into list hanging from io_end. We have to do it | ||
324 | * atomically as bio completions can be racing against each | ||
325 | * other. | ||
326 | */ | ||
327 | bio->bi_private = xchg(&io_end->bio, bio); | ||
328 | } else { | ||
329 | ext4_finish_bio(bio); | ||
330 | bio_put(bio); | ||
331 | } | ||
332 | |||
333 | if (error) { | 322 | if (error) { |
334 | struct inode *inode = io_end->inode; | 323 | struct inode *inode = io_end->inode; |
335 | 324 | ||
@@ -341,7 +330,24 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
341 | (unsigned long long) | 330 | (unsigned long long) |
342 | bi_sector >> (inode->i_blkbits - 9)); | 331 | bi_sector >> (inode->i_blkbits - 9)); |
343 | } | 332 | } |
344 | ext4_put_io_end_defer(io_end); | 333 | |
334 | if (io_end->flag & EXT4_IO_END_UNWRITTEN) { | ||
335 | /* | ||
336 | * Link bio into list hanging from io_end. We have to do it | ||
337 | * atomically as bio completions can be racing against each | ||
338 | * other. | ||
339 | */ | ||
340 | bio->bi_private = xchg(&io_end->bio, bio); | ||
341 | ext4_put_io_end_defer(io_end); | ||
342 | } else { | ||
343 | /* | ||
344 | * Drop io_end reference early. Inode can get freed once | ||
345 | * we finish the bio. | ||
346 | */ | ||
347 | ext4_put_io_end_defer(io_end); | ||
348 | ext4_finish_bio(bio); | ||
349 | bio_put(bio); | ||
350 | } | ||
345 | } | 351 | } |
346 | 352 | ||
347 | void ext4_io_submit(struct ext4_io_submit *io) | 353 | void ext4_io_submit(struct ext4_io_submit *io) |