| @@ -164,6 +164,62 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file) · 163 unmodified lines |
| 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 { · 251 unmodified lines |
| 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) · 14 unmodified lines |
| 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,11 +690,19 @@ static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf) · 180 unmodified lines |
| 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, |
| @@ -639,6 +710,7 @@ static struct attribute *loop_attrs[] = { · 1 unmodified line |
| 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, · 125 unmodified lines |
| 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, · 7 unmodified lines |
| 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) · 212 unmodified lines |
| 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 | |