@@ -164,6 +164,62 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file)
164
164
return get_size (lo -> lo_offset , lo -> lo_sizelimit , file );
165
165
}
166
166
167
+ static void __loop_update_dio (struct loop_device * lo , bool dio )
168
+ {
169
+ struct file * file = lo -> lo_backing_file ;
170
+ struct address_space * mapping = file -> f_mapping ;
171
+ struct inode * inode = mapping -> host ;
172
+ unsigned short sb_bsize = 0 ;
173
+ unsigned dio_align = 0 ;
174
+ bool use_dio ;
175
+
176
+ if (inode -> i_sb -> s_bdev ) {
177
+ sb_bsize = bdev_logical_block_size (inode -> i_sb -> s_bdev );
178
+ dio_align = sb_bsize - 1 ;
179
+ }
180
+
181
+ /*
182
+ * We support direct I/O only if lo_offset is aligned with the
183
+ * logical I/O size of backing device, and the logical block
184
+ * size of loop is bigger than the backing device's and the loop
185
+ * needn't transform transfer.
186
+ *
187
+ * TODO: the above condition may be loosed in the future, and
188
+ * direct I/O may be switched runtime at that time because most
189
+ * of requests in sane appplications should be PAGE_SIZE algined
190
+ */
191
+ if (dio ) {
192
+ if (queue_logical_block_size (lo -> lo_queue ) >= sb_bsize &&
193
+ !(lo -> lo_offset & dio_align ) &&
194
+ mapping -> a_ops -> direct_IO &&
195
+ !lo -> transfer )
196
+ use_dio = true;
197
+ else
198
+ use_dio = false;
199
+ } else {
200
+ use_dio = false;
201
+ }
202
+
203
+ if (lo -> use_dio == use_dio )
204
+ return ;
205
+
206
+ /* flush dirty pages before changing direct IO */
207
+ vfs_fsync (file , 0 );
208
+
209
+ /*
210
+ * The flag of LO_FLAGS_DIRECT_IO is handled similarly with
211
+ * LO_FLAGS_READ_ONLY, both are set from kernel, and losetup
212
+ * will get updated by ioctl(LOOP_GET_STATUS)
213
+ */
214
+ blk_mq_freeze_queue (lo -> lo_queue );
215
+ lo -> use_dio = use_dio ;
216
+ if (use_dio )
217
+ lo -> lo_flags |= LO_FLAGS_DIRECT_IO ;
218
+ else
219
+ lo -> lo_flags &= ~LO_FLAGS_DIRECT_IO ;
220
+ blk_mq_unfreeze_queue (lo -> lo_queue );
221
+ }
222
+
167
223
static int
168
224
figure_loop_size (struct loop_device * lo , loff_t offset , loff_t sizelimit )
169
225
{
@@ -421,6 +477,12 @@ struct switch_request {
421
477
struct completion wait ;
422
478
};
423
479
480
+ static inline void loop_update_dio (struct loop_device * lo )
481
+ {
482
+ __loop_update_dio (lo , io_is_direct (lo -> lo_backing_file ) |
483
+ lo -> use_dio );
484
+ }
485
+
424
486
/*
425
487
* Do the actual switch; called from the BIO completion routine
426
488
*/
@@ -441,6 +503,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
441
503
mapping -> host -> i_bdev -> bd_block_size : PAGE_SIZE ;
442
504
lo -> old_gfp_mask = mapping_gfp_mask (mapping );
443
505
mapping_set_gfp_mask (mapping , lo -> old_gfp_mask & ~(__GFP_IO |__GFP_FS ));
506
+ loop_update_dio (lo );
444
507
}
445
508
446
509
/*
@@ -627,18 +690,27 @@ static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf)
627
690
return sprintf (buf , "%s\n" , partscan ? "1" : "0" );
628
691
}
629
692
693
+ static ssize_t loop_attr_dio_show (struct loop_device * lo , char * buf )
694
+ {
695
+ int dio = (lo -> lo_flags & LO_FLAGS_DIRECT_IO );
696
+
697
+ return sprintf (buf , "%s\n" , dio ? "1" : "0" );
698
+ }
699
+
630
700
LOOP_ATTR_RO (backing_file );
631
701
LOOP_ATTR_RO (offset );
632
702
LOOP_ATTR_RO (sizelimit );
633
703
LOOP_ATTR_RO (autoclear );
634
704
LOOP_ATTR_RO (partscan );
705
+ LOOP_ATTR_RO (dio );
635
706
636
707
static struct attribute * loop_attrs [] = {
637
708
& loop_attr_backing_file .attr ,
638
709
& loop_attr_offset .attr ,
639
710
& loop_attr_sizelimit .attr ,
640
711
& loop_attr_autoclear .attr ,
641
712
& loop_attr_partscan .attr ,
713
+ & loop_attr_dio .attr ,
642
714
NULL ,
643
715
};
644
716
@@ -770,6 +842,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
770
842
771
843
set_device_ro (bdev , (lo_flags & LO_FLAGS_READ_ONLY ) != 0 );
772
844
845
+ lo -> use_dio = false;
773
846
lo -> lo_blocksize = lo_blocksize ;
774
847
lo -> lo_device = bdev ;
775
848
lo -> lo_flags = lo_flags ;
@@ -783,6 +856,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
783
856
if (!(lo_flags & LO_FLAGS_READ_ONLY ) && file -> f_op -> fsync )
784
857
blk_queue_flush (lo -> lo_queue , REQ_FLUSH );
785
858
859
+ loop_update_dio (lo );
786
860
set_capacity (lo -> lo_disk , size );
787
861
bd_set_size (bdev , size << 9 );
788
862
loop_sysfs_init (lo );
@@ -1001,6 +1075,9 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1001
1075
lo -> lo_key_owner = uid ;
1002
1076
}
1003
1077
1078
+ /* update dio if lo_offset or transfer is changed */
1079
+ __loop_update_dio (lo , lo -> use_dio );
1080
+
1004
1081
return 0 ;
1005
1082
}
1006
1083
0 commit comments