OSDN Git Service

loop: fold loop_switch() into callers
authorOmar Sandoval <osandov@fb.com>
Thu, 24 Aug 2017 07:03:44 +0000 (00:03 -0700)
committerJens Axboe <axboe@kernel.dk>
Thu, 31 Aug 2017 19:51:16 +0000 (13:51 -0600)
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>
drivers/block/loop.c

index ac106b2..f6c204f 100644 (file)
@@ -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)
 {
        __loop_update_dio(lo, io_is_direct(lo->lo_backing_file) |
                        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,
                                   struct block_device *bdev)
 {
@@ -676,9 +616,14 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
                goto out_putf;
 
        /* and ... switch */
-       error = loop_switch(lo, file);
-       if (error)
-               goto out_putf;
+       blk_mq_freeze_queue(lo->lo_queue);
+       mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
+       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);
        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);
                if (!err)
                        return;
-       } else {
+       } else if (lo->lo_state == Lo_bound) {
                /*
                 * Otherwise keep thread (if running) and config,
                 * 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);