aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2008-12-12 08:48:27 -0500
committerJens Axboe <jens.axboe@oracle.com>2008-12-29 02:29:52 -0500
commit14f2793958bd7878db2dc0309ed4525d6b7f1b72 (patch)
tree6113ae1d21963b96e10a5174d2c3365b1f0570fd /drivers/block
parent10e5b64415ae9a0ba81dd1f1036d14dfdae9308c (diff)
loop: Flush possible running bios when loop device is released.
When there are still queued bios and reference count drops to zero, loop device must flush all queued bios. Otherwise it can lead to situation that caller closes the device, but some bios are still running and endio() function call later OOpses when uses unallocated mempool. This happens for example when running dm-crypt over loop, here is typical oops backtrace: Oops: 0000 [#1] PREEMPT SMP EIP is at mempool_free+0x12/0x6b ... crypt_dec_pending+0x50/0x54 [dm_crypt] crypt_endio+0x9f/0xa7 [dm_crypt] crypt_endio+0x0/0xa7 [dm_crypt] bio_endio+0x2b/0x2e loop_thread+0x37a/0x3b1 do_lo_send_aops+0x0/0x165 autoremove_wake_function+0x0/0x33 loop_thread+0x0/0x3b1 kthread+0x3b/0x61 kthread+0x0/0x61 kernel_thread_helper+0x7/0x10 (But crash is reproducible with different dm targets running over loop device too.) Patch fixes it by flushing the bios in release call, reusing the flush mechanism for switching backing store. Signed-off-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/loop.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index fb06ed659212..66cfff79938e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -624,20 +624,38 @@ static int loop_switch(struct loop_device *lo, struct file *file)
624} 624}
625 625
626/* 626/*
627 * Helper to flush the IOs in loop, but keeping loop thread running
628 */
629static int loop_flush(struct loop_device *lo)
630{
631 /* loop not yet configured, no running thread, nothing to flush */
632 if (!lo->lo_thread)
633 return 0;
634
635 return loop_switch(lo, NULL);
636}
637
638/*
627 * Do the actual switch; called from the BIO completion routine 639 * Do the actual switch; called from the BIO completion routine
628 */ 640 */
629static void do_loop_switch(struct loop_device *lo, struct switch_request *p) 641static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
630{ 642{
631 struct file *file = p->file; 643 struct file *file = p->file;
632 struct file *old_file = lo->lo_backing_file; 644 struct file *old_file = lo->lo_backing_file;
633 struct address_space *mapping = file->f_mapping; 645 struct address_space *mapping;
646
647 /* if no new file, only flush of queued bios requested */
648 if (!file)
649 goto out;
634 650
651 mapping = file->f_mapping;
635 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); 652 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
636 lo->lo_backing_file = file; 653 lo->lo_backing_file = file;
637 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ? 654 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
638 mapping->host->i_bdev->bd_block_size : PAGE_SIZE; 655 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
639 lo->old_gfp_mask = mapping_gfp_mask(mapping); 656 lo->old_gfp_mask = mapping_gfp_mask(mapping);
640 mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); 657 mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
658out:
641 complete(&p->wait); 659 complete(&p->wait);
642} 660}
643 661
@@ -1345,11 +1363,25 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
1345 struct loop_device *lo = disk->private_data; 1363 struct loop_device *lo = disk->private_data;
1346 1364
1347 mutex_lock(&lo->lo_ctl_mutex); 1365 mutex_lock(&lo->lo_ctl_mutex);
1348 --lo->lo_refcnt;
1349 1366
1350 if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt) 1367 if (--lo->lo_refcnt)
1368 goto out;
1369
1370 if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
1371 /*
1372 * In autoclear mode, stop the loop thread
1373 * and remove configuration after last close.
1374 */
1351 loop_clr_fd(lo, NULL); 1375 loop_clr_fd(lo, NULL);
1376 } else {
1377 /*
1378 * Otherwise keep thread (if running) and config,
1379 * but flush possible ongoing bios in thread.
1380 */
1381 loop_flush(lo);
1382 }
1352 1383
1384out:
1353 mutex_unlock(&lo->lo_ctl_mutex); 1385 mutex_unlock(&lo->lo_ctl_mutex);
1354 1386
1355 return 0; 1387 return 0;