diff options
| -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) |
