| @@ -164,6 +164,62 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file) · 163 unmodified lines |
| 164 | return get_size(lo->lo_offset, lo->lo_sizelimit, file); | 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 | static int | 223 | static int |
| 168 | figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) | 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 | struct completion wait; | 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 | * Do the actual switch; called from the BIO completion routine | 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 | mapping->host->i_bdev->bd_block_size : PAGE_SIZE; | 503 | mapping->host->i_bdev->bd_block_size : PAGE_SIZE; |
| 442 | lo->old_gfp_mask = mapping_gfp_mask(mapping); | 504 | lo->old_gfp_mask = mapping_gfp_mask(mapping); |
| 443 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); | 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 | return sprintf(buf, "%s\n", partscan ? "1" : "0"); | 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 | LOOP_ATTR_RO(backing_file); | 700 | LOOP_ATTR_RO(backing_file); |
| 631 | LOOP_ATTR_RO(offset); | 701 | LOOP_ATTR_RO(offset); |
| 632 | LOOP_ATTR_RO(sizelimit); | 702 | LOOP_ATTR_RO(sizelimit); |
| 633 | LOOP_ATTR_RO(autoclear); | 703 | LOOP_ATTR_RO(autoclear); |
| 634 | LOOP_ATTR_RO(partscan); | 704 | LOOP_ATTR_RO(partscan); |
| | 705 | LOOP_ATTR_RO(dio); |
| 635 | | 706 | |
| 636 | static struct attribute *loop_attrs[] = { | 707 | static struct attribute *loop_attrs[] = { |
| 637 | &loop_attr_backing_file.attr, | 708 | &loop_attr_backing_file.attr, |
| @@ -639,6 +710,7 @@ static struct attribute *loop_attrs[] = { · 1 unmodified line |
| 639 | &loop_attr_sizelimit.attr, | 710 | &loop_attr_sizelimit.attr, |
| 640 | &loop_attr_autoclear.attr, | 711 | &loop_attr_autoclear.attr, |
| 641 | &loop_attr_partscan.attr, | 712 | &loop_attr_partscan.attr, |
| | 713 | &loop_attr_dio.attr, |
| 642 | NULL, | 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 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); | 843 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); |
| 772 | | 844 | |
| | 845 | lo->use_dio = false; |
| 773 | lo->lo_blocksize = lo_blocksize; | 846 | lo->lo_blocksize = lo_blocksize; |
| 774 | lo->lo_device = bdev; | 847 | lo->lo_device = bdev; |
| 775 | lo->lo_flags = lo_flags; | 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 | if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) | 856 | if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) |
| 784 | blk_queue_flush(lo->lo_queue, REQ_FLUSH); | 857 | blk_queue_flush(lo->lo_queue, REQ_FLUSH); |
| 785 | | 858 | |
| | 859 | loop_update_dio(lo); |
| 786 | set_capacity(lo->lo_disk, size); | 860 | set_capacity(lo->lo_disk, size); |
| 787 | bd_set_size(bdev, size << 9); | 861 | bd_set_size(bdev, size << 9); |
| 788 | loop_sysfs_init(lo); | 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 | lo->lo_key_owner = uid; | 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 | return 0; | 1081 | return 0; |
| 1005 | } | 1082 | } |
| 1006 | | 1083 | |