/* freeze queue and wait for completion of scheduled requests */
blk_mq_freeze_queue(lo->lo_queue);
@@ -617,7 +620,16 @@ static int loop_switch(struct loop_device *lo, struct file *file)
- */
- 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);
+ return loop_switch(lo, NULL, NULL);
+}
struct inode *inode;
int error;
-@@ -670,9 +683,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+@@ -670,13 +683,20 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
file = fget(arg);
if (!file)
goto out;
+ get_file(file);
+ }
+ error = loop_validate_file(file, bdev);
+ if (error)
+ goto out_putf;
+
inode = file->f_mapping->host;
old_file = lo->lo_backing_file;
+ old_virt_file = lo->lo_backing_virt_file;
static int loop_set_fd(struct loop_device *lo, fmode_t mode,
struct block_device *bdev, unsigned int arg)
{
-- struct file *file, *f;
+- struct file *file;
+ struct file *file, *f, *virt_file = NULL;
struct inode *inode;
struct address_space *mapping;