diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0000913f7efcc..ff117f340b2f9 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1118,6 +1118,17 @@ static void __loop_clr_fd(struct loop_device *lo) struct file *filp; gfp_t gfp = lo->old_gfp_mask; + /* + * Now that loop_queue_rq() sees lo->lo_state != Lo_bound, + * wait for already started loop_queue_rq() to complete. + */ + synchronize_rcu(); + /* + * Now that no more works are scheduled by loop_queue_rq(), + * wait for already scheduled works to complete. + */ + drain_workqueue(lo->workqueue); + spin_lock_irq(&lo->lo_lock); filp = lo->lo_backing_file; lo->lo_backing_file = NULL;