mirror of https://gitee.com/openkylin/linux.git
loop: fold loop_switch() into callers
The comments here are really outdated, and blk-mq made flushing much simpler, so just fold the two cases into the callers. Reviewed-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
89e4fdecb5
commit
43cade803e
|
@ -546,72 +546,12 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct switch_request {
|
|
||||||
struct file *file;
|
|
||||||
struct completion wait;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void loop_update_dio(struct loop_device *lo)
|
static inline void loop_update_dio(struct loop_device *lo)
|
||||||
{
|
{
|
||||||
__loop_update_dio(lo, io_is_direct(lo->lo_backing_file) |
|
__loop_update_dio(lo, io_is_direct(lo->lo_backing_file) |
|
||||||
lo->use_dio);
|
lo->use_dio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the actual switch; called from the BIO completion routine
|
|
||||||
*/
|
|
||||||
static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
|
|
||||||
{
|
|
||||||
struct file *file = p->file;
|
|
||||||
struct file *old_file = lo->lo_backing_file;
|
|
||||||
struct address_space *mapping;
|
|
||||||
|
|
||||||
/* if no new file, only flush of queued bios requested */
|
|
||||||
if (!file)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mapping = file->f_mapping;
|
|
||||||
mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
|
|
||||||
lo->lo_backing_file = file;
|
|
||||||
lo->old_gfp_mask = mapping_gfp_mask(mapping);
|
|
||||||
mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
|
|
||||||
loop_update_dio(lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* loop_switch performs the hard work of switching a backing store.
|
|
||||||
* First it needs to flush existing IO, it does this by sending a magic
|
|
||||||
* BIO down the pipe. The completion of this BIO does the actual switch.
|
|
||||||
*/
|
|
||||||
static int loop_switch(struct loop_device *lo, struct file *file)
|
|
||||||
{
|
|
||||||
struct switch_request w;
|
|
||||||
|
|
||||||
w.file = file;
|
|
||||||
|
|
||||||
/* freeze queue and wait for completion of scheduled requests */
|
|
||||||
blk_mq_freeze_queue(lo->lo_queue);
|
|
||||||
|
|
||||||
/* do the switch action */
|
|
||||||
do_loop_switch(lo, &w);
|
|
||||||
|
|
||||||
/* unfreeze */
|
|
||||||
blk_mq_unfreeze_queue(lo->lo_queue);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper to flush the IOs in loop, but keeping loop thread running
|
|
||||||
*/
|
|
||||||
static int loop_flush(struct loop_device *lo)
|
|
||||||
{
|
|
||||||
/* loop not yet configured, no running thread, nothing to flush */
|
|
||||||
if (lo->lo_state != Lo_bound)
|
|
||||||
return 0;
|
|
||||||
return loop_switch(lo, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void loop_reread_partitions(struct loop_device *lo,
|
static void loop_reread_partitions(struct loop_device *lo,
|
||||||
struct block_device *bdev)
|
struct block_device *bdev)
|
||||||
{
|
{
|
||||||
|
@ -676,9 +616,14 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
|
||||||
goto out_putf;
|
goto out_putf;
|
||||||
|
|
||||||
/* and ... switch */
|
/* and ... switch */
|
||||||
error = loop_switch(lo, file);
|
blk_mq_freeze_queue(lo->lo_queue);
|
||||||
if (error)
|
mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
|
||||||
goto out_putf;
|
lo->lo_backing_file = file;
|
||||||
|
lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping);
|
||||||
|
mapping_set_gfp_mask(file->f_mapping,
|
||||||
|
lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
|
||||||
|
loop_update_dio(lo);
|
||||||
|
blk_mq_unfreeze_queue(lo->lo_queue);
|
||||||
|
|
||||||
fput(old_file);
|
fput(old_file);
|
||||||
if (lo->lo_flags & LO_FLAGS_PARTSCAN)
|
if (lo->lo_flags & LO_FLAGS_PARTSCAN)
|
||||||
|
@ -1601,12 +1546,13 @@ static void lo_release(struct gendisk *disk, fmode_t mode)
|
||||||
err = loop_clr_fd(lo);
|
err = loop_clr_fd(lo);
|
||||||
if (!err)
|
if (!err)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else if (lo->lo_state == Lo_bound) {
|
||||||
/*
|
/*
|
||||||
* Otherwise keep thread (if running) and config,
|
* Otherwise keep thread (if running) and config,
|
||||||
* but flush possible ongoing bios in thread.
|
* but flush possible ongoing bios in thread.
|
||||||
*/
|
*/
|
||||||
loop_flush(lo);
|
blk_mq_freeze_queue(lo->lo_queue);
|
||||||
|
blk_mq_unfreeze_queue(lo->lo_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&lo->lo_ctl_mutex);
|
mutex_unlock(&lo->lo_ctl_mutex);
|
||||||
|
|
Loading…
Reference in New Issue