summaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2017-06-08 07:46:45 -0400
committerJens Axboe <axboe@fb.com>2017-06-08 10:40:00 -0400
commitf2c6df7dbf9a60e1cd9941f9fb376d4d9ad1e8dd (patch)
tree79a9c0d9627fa253955532d6925e9606e1643f72 /drivers/block/loop.c
parent51001b7da364a24ed2464f3c22179efdc6b3a960 (diff)
loop: support 4k physical blocksize
When generating bootable VM images certain systems (most notably s390x) require devices with 4k blocksize. This patch implements a new flag 'LO_FLAGS_BLOCKSIZE' which will set the physical blocksize to that of the underlying device, and allow to change the logical blocksize for up to the physical blocksize. Signed-off-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index fc706adff6a4..4d376c10a97a 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -221,7 +221,8 @@ static void __loop_update_dio(struct loop_device *lo, bool dio)
221} 221}
222 222
223static int 223static int
224figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) 224figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit,
225 loff_t logical_blocksize)
225{ 226{
226 loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); 227 loff_t size = get_size(offset, sizelimit, lo->lo_backing_file);
227 sector_t x = (sector_t)size; 228 sector_t x = (sector_t)size;
@@ -233,6 +234,12 @@ figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit)
233 lo->lo_offset = offset; 234 lo->lo_offset = offset;
234 if (lo->lo_sizelimit != sizelimit) 235 if (lo->lo_sizelimit != sizelimit)
235 lo->lo_sizelimit = sizelimit; 236 lo->lo_sizelimit = sizelimit;
237 if (lo->lo_flags & LO_FLAGS_BLOCKSIZE) {
238 lo->lo_logical_blocksize = logical_blocksize;
239 blk_queue_physical_block_size(lo->lo_queue, lo->lo_blocksize);
240 blk_queue_logical_block_size(lo->lo_queue,
241 lo->lo_logical_blocksize);
242 }
236 set_capacity(lo->lo_disk, x); 243 set_capacity(lo->lo_disk, x);
237 bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9); 244 bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9);
238 /* let user-space know about the new size */ 245 /* let user-space know about the new size */
@@ -810,6 +817,7 @@ static void loop_config_discard(struct loop_device *lo)
810 struct file *file = lo->lo_backing_file; 817 struct file *file = lo->lo_backing_file;
811 struct inode *inode = file->f_mapping->host; 818 struct inode *inode = file->f_mapping->host;
812 struct request_queue *q = lo->lo_queue; 819 struct request_queue *q = lo->lo_queue;
820 int lo_bits = 9;
813 821
814 /* 822 /*
815 * We use punch hole to reclaim the free space used by the 823 * We use punch hole to reclaim the free space used by the
@@ -829,8 +837,11 @@ static void loop_config_discard(struct loop_device *lo)
829 837
830 q->limits.discard_granularity = inode->i_sb->s_blocksize; 838 q->limits.discard_granularity = inode->i_sb->s_blocksize;
831 q->limits.discard_alignment = 0; 839 q->limits.discard_alignment = 0;
832 blk_queue_max_discard_sectors(q, UINT_MAX >> 9); 840 if (lo->lo_flags & LO_FLAGS_BLOCKSIZE)
833 blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9); 841 lo_bits = blksize_bits(lo->lo_logical_blocksize);
842
843 blk_queue_max_discard_sectors(q, UINT_MAX >> lo_bits);
844 blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> lo_bits);
834 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); 845 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
835} 846}
836 847
@@ -918,6 +929,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
918 929
919 lo->use_dio = false; 930 lo->use_dio = false;
920 lo->lo_blocksize = lo_blocksize; 931 lo->lo_blocksize = lo_blocksize;
932 lo->lo_logical_blocksize = 512;
921 lo->lo_device = bdev; 933 lo->lo_device = bdev;
922 lo->lo_flags = lo_flags; 934 lo->lo_flags = lo_flags;
923 lo->lo_backing_file = file; 935 lo->lo_backing_file = file;
@@ -1083,6 +1095,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1083 int err; 1095 int err;
1084 struct loop_func_table *xfer; 1096 struct loop_func_table *xfer;
1085 kuid_t uid = current_uid(); 1097 kuid_t uid = current_uid();
1098 int lo_flags = lo->lo_flags;
1086 1099
1087 if (lo->lo_encrypt_key_size && 1100 if (lo->lo_encrypt_key_size &&
1088 !uid_eq(lo->lo_key_owner, uid) && 1101 !uid_eq(lo->lo_key_owner, uid) &&
@@ -1115,9 +1128,26 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1115 if (err) 1128 if (err)
1116 goto exit; 1129 goto exit;
1117 1130
1131 if (info->lo_flags & LO_FLAGS_BLOCKSIZE) {
1132 if (!(lo->lo_flags & LO_FLAGS_BLOCKSIZE))
1133 lo->lo_logical_blocksize = 512;
1134 lo->lo_flags |= LO_FLAGS_BLOCKSIZE;
1135 if (LO_INFO_BLOCKSIZE(info) != 512 &&
1136 LO_INFO_BLOCKSIZE(info) != 1024 &&
1137 LO_INFO_BLOCKSIZE(info) != 2048 &&
1138 LO_INFO_BLOCKSIZE(info) != 4096)
1139 return -EINVAL;
1140 if (LO_INFO_BLOCKSIZE(info) > lo->lo_blocksize)
1141 return -EINVAL;
1142 }
1143
1118 if (lo->lo_offset != info->lo_offset || 1144 if (lo->lo_offset != info->lo_offset ||
1119 lo->lo_sizelimit != info->lo_sizelimit) 1145 lo->lo_sizelimit != info->lo_sizelimit ||
1120 if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) { 1146 lo->lo_flags != lo_flags ||
1147 ((lo->lo_flags & LO_FLAGS_BLOCKSIZE) &&
1148 lo->lo_logical_blocksize != LO_INFO_BLOCKSIZE(info))) {
1149 if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit,
1150 LO_INFO_BLOCKSIZE(info)))
1121 err = -EFBIG; 1151 err = -EFBIG;
1122 goto exit; 1152 goto exit;
1123 } 1153 }
@@ -1308,7 +1338,8 @@ static int loop_set_capacity(struct loop_device *lo)
1308 if (unlikely(lo->lo_state != Lo_bound)) 1338 if (unlikely(lo->lo_state != Lo_bound))
1309 return -ENXIO; 1339 return -ENXIO;
1310 1340
1311 return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); 1341 return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit,
1342 lo->lo_logical_blocksize);
1312} 1343}
1313 1344
1314static int loop_set_dio(struct loop_device *lo, unsigned long arg) 1345static int loop_set_dio(struct loop_device *lo, unsigned long arg)