--- x/drivers/block/loop.c +++ y/drivers/block/loop.c @@ -443,9 +443,8 @@ static void loop_reread_partitions(struc __func__, lo->lo_number, lo->lo_file_name, rc); } -static unsigned int loop_query_min_dio_size(struct loop_device *lo) +static unsigned int loop_query_min_dio_size(struct file *file) { - struct file *file = lo->lo_backing_file; struct block_device *sb_bdev = file->f_mapping->host->i_sb->s_bdev; struct kstat st; @@ -497,7 +496,8 @@ static int loop_validate_file(struct fil return 0; } -static void loop_assign_backing_file(struct loop_device *lo, struct file *file) +static void loop_assign_backing_file(struct loop_device *lo, struct file *file, + unsigned int min_dio_size) { lo->lo_backing_file = file; lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping); @@ -505,7 +505,7 @@ static void loop_assign_backing_file(str lo->old_gfp_mask & ~(__GFP_IO | __GFP_FS)); if (lo->lo_backing_file->f_flags & O_DIRECT) lo->lo_flags |= LO_FLAGS_DIRECT_IO; - lo->lo_min_dio_size = loop_query_min_dio_size(lo); + lo->lo_min_dio_size = min_dio_size; } static int loop_check_backing_file(struct file *file) @@ -532,7 +532,7 @@ static int loop_change_fd(struct loop_de { struct file *file = fget(arg); struct file *old_file; - unsigned int memflags; + unsigned int memflags, blksz; int error; bool partscan; bool is_loop; @@ -581,9 +581,10 @@ static int loop_change_fd(struct loop_de /* and ... switch */ disk_force_media_change(lo->lo_disk); + blksz = loop_query_min_dio_size(file); memflags = blk_mq_freeze_queue(lo->lo_queue); mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); - loop_assign_backing_file(lo, file); + loop_assign_backing_file(lo, file, blksz); loop_update_dio(lo); blk_mq_unfreeze_queue(lo->lo_queue, memflags); partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; @@ -974,6 +975,7 @@ static int loop_configure(struct loop_de { struct file *file = fget(config->fd); struct queue_limits lim; + unsigned int blksz; int error; loff_t size; bool partscan; @@ -1043,8 +1045,9 @@ static int loop_configure(struct loop_de disk_force_media_change(lo->lo_disk); set_disk_ro(lo->lo_disk, (lo->lo_flags & LO_FLAGS_READ_ONLY) != 0); + blksz = loop_query_min_dio_size(file); lo->lo_device = bdev; - loop_assign_backing_file(lo, file); + loop_assign_backing_file(lo, file, blksz); lim = queue_limits_start_update(lo->lo_queue); loop_update_limits(lo, &lim, config->block_size);