0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "dm.h"
0013 #include <linux/module.h>
0014 #include <linux/workqueue.h>
0015 #include <linux/dm-bufio.h>
0016
0017 #define DM_MSG_PREFIX "ebs"
0018
0019 static void ebs_dtr(struct dm_target *ti);
0020
0021
0022 struct ebs_c {
0023 struct dm_dev *dev;
0024 struct dm_bufio_client *bufio;
0025 struct workqueue_struct *wq;
0026 struct work_struct ws;
0027 struct bio_list bios_in;
0028 spinlock_t lock;
0029 sector_t start;
0030 unsigned int e_bs;
0031 unsigned int u_bs;
0032 unsigned char block_shift;
0033 bool u_bs_set:1;
0034 };
0035
0036 static inline sector_t __sector_to_block(struct ebs_c *ec, sector_t sector)
0037 {
0038 return sector >> ec->block_shift;
0039 }
0040
0041 static inline sector_t __block_mod(sector_t sector, unsigned int bs)
0042 {
0043 return sector & (bs - 1);
0044 }
0045
0046
0047 static inline unsigned int __nr_blocks(struct ebs_c *ec, struct bio *bio)
0048 {
0049 sector_t end_sector = __block_mod(bio->bi_iter.bi_sector, ec->u_bs) + bio_sectors(bio);
0050
0051 return __sector_to_block(ec, end_sector) + (__block_mod(end_sector, ec->u_bs) ? 1 : 0);
0052 }
0053
0054 static inline bool __ebs_check_bs(unsigned int bs)
0055 {
0056 return bs && is_power_of_2(bs);
0057 }
0058
0059
0060
0061
0062
0063
0064 static int __ebs_rw_bvec(struct ebs_c *ec, enum req_op op, struct bio_vec *bv,
0065 struct bvec_iter *iter)
0066 {
0067 int r = 0;
0068 unsigned char *ba, *pa;
0069 unsigned int cur_len;
0070 unsigned int bv_len = bv->bv_len;
0071 unsigned int buf_off = to_bytes(__block_mod(iter->bi_sector, ec->u_bs));
0072 sector_t block = __sector_to_block(ec, iter->bi_sector);
0073 struct dm_buffer *b;
0074
0075 if (unlikely(!bv->bv_page || !bv_len))
0076 return -EIO;
0077
0078 pa = bvec_virt(bv);
0079
0080
0081 while (bv_len) {
0082 cur_len = min(dm_bufio_get_block_size(ec->bufio) - buf_off, bv_len);
0083
0084
0085 if (op == REQ_OP_READ || buf_off || bv_len < dm_bufio_get_block_size(ec->bufio))
0086 ba = dm_bufio_read(ec->bufio, block, &b);
0087 else
0088 ba = dm_bufio_new(ec->bufio, block, &b);
0089
0090 if (IS_ERR(ba)) {
0091
0092
0093
0094
0095 r = PTR_ERR(ba);
0096 } else {
0097
0098 ba += buf_off;
0099 if (op == REQ_OP_READ) {
0100 memcpy(pa, ba, cur_len);
0101 flush_dcache_page(bv->bv_page);
0102 } else {
0103 flush_dcache_page(bv->bv_page);
0104 memcpy(ba, pa, cur_len);
0105 dm_bufio_mark_partial_buffer_dirty(b, buf_off, buf_off + cur_len);
0106 }
0107
0108 dm_bufio_release(b);
0109 }
0110
0111 pa += cur_len;
0112 bv_len -= cur_len;
0113 buf_off = 0;
0114 block++;
0115 }
0116
0117 return r;
0118 }
0119
0120
0121 static int __ebs_rw_bio(struct ebs_c *ec, enum req_op op, struct bio *bio)
0122 {
0123 int r = 0, rr;
0124 struct bio_vec bv;
0125 struct bvec_iter iter;
0126
0127 bio_for_each_bvec(bv, bio, iter) {
0128 rr = __ebs_rw_bvec(ec, op, &bv, &iter);
0129 if (rr)
0130 r = rr;
0131 }
0132
0133 return r;
0134 }
0135
0136
0137
0138
0139
0140
0141
0142 static int __ebs_discard_bio(struct ebs_c *ec, struct bio *bio)
0143 {
0144 sector_t block, blocks, sector = bio->bi_iter.bi_sector;
0145
0146 block = __sector_to_block(ec, sector);
0147 blocks = __nr_blocks(ec, bio);
0148
0149
0150
0151
0152
0153 if (__block_mod(sector, ec->u_bs)) {
0154 block++;
0155 blocks--;
0156 }
0157
0158
0159 if (blocks && __block_mod(bio_end_sector(bio), ec->u_bs))
0160 blocks--;
0161
0162 return blocks ? dm_bufio_issue_discard(ec->bufio, block, blocks) : 0;
0163 }
0164
0165
0166 static void __ebs_forget_bio(struct ebs_c *ec, struct bio *bio)
0167 {
0168 sector_t blocks, sector = bio->bi_iter.bi_sector;
0169
0170 blocks = __nr_blocks(ec, bio);
0171
0172 dm_bufio_forget_buffers(ec->bufio, __sector_to_block(ec, sector), blocks);
0173 }
0174
0175
0176 static void __ebs_process_bios(struct work_struct *ws)
0177 {
0178 int r;
0179 bool write = false;
0180 sector_t block1, block2;
0181 struct ebs_c *ec = container_of(ws, struct ebs_c, ws);
0182 struct bio *bio;
0183 struct bio_list bios;
0184
0185 bio_list_init(&bios);
0186
0187 spin_lock_irq(&ec->lock);
0188 bios = ec->bios_in;
0189 bio_list_init(&ec->bios_in);
0190 spin_unlock_irq(&ec->lock);
0191
0192
0193 bio_list_for_each(bio, &bios) {
0194 block1 = __sector_to_block(ec, bio->bi_iter.bi_sector);
0195 if (bio_op(bio) == REQ_OP_READ)
0196 dm_bufio_prefetch(ec->bufio, block1, __nr_blocks(ec, bio));
0197 else if (bio_op(bio) == REQ_OP_WRITE && !(bio->bi_opf & REQ_PREFLUSH)) {
0198 block2 = __sector_to_block(ec, bio_end_sector(bio));
0199 if (__block_mod(bio->bi_iter.bi_sector, ec->u_bs))
0200 dm_bufio_prefetch(ec->bufio, block1, 1);
0201 if (__block_mod(bio_end_sector(bio), ec->u_bs) && block2 != block1)
0202 dm_bufio_prefetch(ec->bufio, block2, 1);
0203 }
0204 }
0205
0206 bio_list_for_each(bio, &bios) {
0207 r = -EIO;
0208 if (bio_op(bio) == REQ_OP_READ)
0209 r = __ebs_rw_bio(ec, REQ_OP_READ, bio);
0210 else if (bio_op(bio) == REQ_OP_WRITE) {
0211 write = true;
0212 r = __ebs_rw_bio(ec, REQ_OP_WRITE, bio);
0213 } else if (bio_op(bio) == REQ_OP_DISCARD) {
0214 __ebs_forget_bio(ec, bio);
0215 r = __ebs_discard_bio(ec, bio);
0216 }
0217
0218 if (r < 0)
0219 bio->bi_status = errno_to_blk_status(r);
0220 }
0221
0222
0223
0224
0225
0226 r = write ? dm_bufio_write_dirty_buffers(ec->bufio) : 0;
0227
0228 while ((bio = bio_list_pop(&bios))) {
0229
0230 if (unlikely(r && bio_op(bio) == REQ_OP_WRITE))
0231 bio_io_error(bio);
0232 else
0233 bio_endio(bio);
0234 }
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 static int ebs_ctr(struct dm_target *ti, unsigned int argc, char **argv)
0247 {
0248 int r;
0249 unsigned short tmp1;
0250 unsigned long long tmp;
0251 char dummy;
0252 struct ebs_c *ec;
0253
0254 if (argc < 3 || argc > 4) {
0255 ti->error = "Invalid argument count";
0256 return -EINVAL;
0257 }
0258
0259 ec = ti->private = kzalloc(sizeof(*ec), GFP_KERNEL);
0260 if (!ec) {
0261 ti->error = "Cannot allocate ebs context";
0262 return -ENOMEM;
0263 }
0264
0265 r = -EINVAL;
0266 if (sscanf(argv[1], "%llu%c", &tmp, &dummy) != 1 ||
0267 tmp != (sector_t)tmp ||
0268 (sector_t)tmp >= ti->len) {
0269 ti->error = "Invalid device offset sector";
0270 goto bad;
0271 }
0272 ec->start = tmp;
0273
0274 if (sscanf(argv[2], "%hu%c", &tmp1, &dummy) != 1 ||
0275 !__ebs_check_bs(tmp1) ||
0276 to_bytes(tmp1) > PAGE_SIZE) {
0277 ti->error = "Invalid emulated block size";
0278 goto bad;
0279 }
0280 ec->e_bs = tmp1;
0281
0282 if (argc > 3) {
0283 if (sscanf(argv[3], "%hu%c", &tmp1, &dummy) != 1 || !__ebs_check_bs(tmp1)) {
0284 ti->error = "Invalid underlying block size";
0285 goto bad;
0286 }
0287 ec->u_bs = tmp1;
0288 ec->u_bs_set = true;
0289 } else
0290 ec->u_bs_set = false;
0291
0292 r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &ec->dev);
0293 if (r) {
0294 ti->error = "Device lookup failed";
0295 ec->dev = NULL;
0296 goto bad;
0297 }
0298
0299 r = -EINVAL;
0300 if (!ec->u_bs_set) {
0301 ec->u_bs = to_sector(bdev_logical_block_size(ec->dev->bdev));
0302 if (!__ebs_check_bs(ec->u_bs)) {
0303 ti->error = "Invalid retrieved underlying block size";
0304 goto bad;
0305 }
0306 }
0307
0308 if (!ec->u_bs_set && ec->e_bs == ec->u_bs)
0309 DMINFO("Emulation superfluous: emulated equal to underlying block size");
0310
0311 if (__block_mod(ec->start, ec->u_bs)) {
0312 ti->error = "Device offset must be multiple of underlying block size";
0313 goto bad;
0314 }
0315
0316 ec->bufio = dm_bufio_client_create(ec->dev->bdev, to_bytes(ec->u_bs), 1,
0317 0, NULL, NULL, 0);
0318 if (IS_ERR(ec->bufio)) {
0319 ti->error = "Cannot create dm bufio client";
0320 r = PTR_ERR(ec->bufio);
0321 ec->bufio = NULL;
0322 goto bad;
0323 }
0324
0325 ec->wq = alloc_ordered_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM);
0326 if (!ec->wq) {
0327 ti->error = "Cannot create dm-" DM_MSG_PREFIX " workqueue";
0328 r = -ENOMEM;
0329 goto bad;
0330 }
0331
0332 ec->block_shift = __ffs(ec->u_bs);
0333 INIT_WORK(&ec->ws, &__ebs_process_bios);
0334 bio_list_init(&ec->bios_in);
0335 spin_lock_init(&ec->lock);
0336
0337 ti->num_flush_bios = 1;
0338 ti->num_discard_bios = 1;
0339 ti->num_secure_erase_bios = 0;
0340 ti->num_write_zeroes_bios = 0;
0341 return 0;
0342 bad:
0343 ebs_dtr(ti);
0344 return r;
0345 }
0346
0347 static void ebs_dtr(struct dm_target *ti)
0348 {
0349 struct ebs_c *ec = ti->private;
0350
0351 if (ec->wq)
0352 destroy_workqueue(ec->wq);
0353 if (ec->bufio)
0354 dm_bufio_client_destroy(ec->bufio);
0355 if (ec->dev)
0356 dm_put_device(ti, ec->dev);
0357 kfree(ec);
0358 }
0359
0360 static int ebs_map(struct dm_target *ti, struct bio *bio)
0361 {
0362 struct ebs_c *ec = ti->private;
0363
0364 bio_set_dev(bio, ec->dev->bdev);
0365 bio->bi_iter.bi_sector = ec->start + dm_target_offset(ti, bio->bi_iter.bi_sector);
0366
0367 if (unlikely(bio_op(bio) == REQ_OP_FLUSH))
0368 return DM_MAPIO_REMAPPED;
0369
0370
0371
0372
0373
0374 if (likely(__block_mod(bio->bi_iter.bi_sector, ec->u_bs) ||
0375 __block_mod(bio_end_sector(bio), ec->u_bs) ||
0376 ec->e_bs == ec->u_bs)) {
0377 spin_lock_irq(&ec->lock);
0378 bio_list_add(&ec->bios_in, bio);
0379 spin_unlock_irq(&ec->lock);
0380
0381 queue_work(ec->wq, &ec->ws);
0382
0383 return DM_MAPIO_SUBMITTED;
0384 }
0385
0386
0387 __ebs_forget_bio(ec, bio);
0388
0389 return DM_MAPIO_REMAPPED;
0390 }
0391
0392 static void ebs_status(struct dm_target *ti, status_type_t type,
0393 unsigned status_flags, char *result, unsigned maxlen)
0394 {
0395 struct ebs_c *ec = ti->private;
0396
0397 switch (type) {
0398 case STATUSTYPE_INFO:
0399 *result = '\0';
0400 break;
0401 case STATUSTYPE_TABLE:
0402 snprintf(result, maxlen, ec->u_bs_set ? "%s %llu %u %u" : "%s %llu %u",
0403 ec->dev->name, (unsigned long long) ec->start, ec->e_bs, ec->u_bs);
0404 break;
0405 case STATUSTYPE_IMA:
0406 *result = '\0';
0407 break;
0408 }
0409 }
0410
0411 static int ebs_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
0412 {
0413 struct ebs_c *ec = ti->private;
0414 struct dm_dev *dev = ec->dev;
0415
0416
0417
0418
0419 *bdev = dev->bdev;
0420 return !!(ec->start || ti->len != bdev_nr_sectors(dev->bdev));
0421 }
0422
0423 static void ebs_io_hints(struct dm_target *ti, struct queue_limits *limits)
0424 {
0425 struct ebs_c *ec = ti->private;
0426
0427 limits->logical_block_size = to_bytes(ec->e_bs);
0428 limits->physical_block_size = to_bytes(ec->u_bs);
0429 limits->alignment_offset = limits->physical_block_size;
0430 blk_limits_io_min(limits, limits->logical_block_size);
0431 }
0432
0433 static int ebs_iterate_devices(struct dm_target *ti,
0434 iterate_devices_callout_fn fn, void *data)
0435 {
0436 struct ebs_c *ec = ti->private;
0437
0438 return fn(ti, ec->dev, ec->start, ti->len, data);
0439 }
0440
0441 static struct target_type ebs_target = {
0442 .name = "ebs",
0443 .version = {1, 0, 1},
0444 .features = DM_TARGET_PASSES_INTEGRITY,
0445 .module = THIS_MODULE,
0446 .ctr = ebs_ctr,
0447 .dtr = ebs_dtr,
0448 .map = ebs_map,
0449 .status = ebs_status,
0450 .io_hints = ebs_io_hints,
0451 .prepare_ioctl = ebs_prepare_ioctl,
0452 .iterate_devices = ebs_iterate_devices,
0453 };
0454
0455 static int __init dm_ebs_init(void)
0456 {
0457 int r = dm_register_target(&ebs_target);
0458
0459 if (r < 0)
0460 DMERR("register failed %d", r);
0461
0462 return r;
0463 }
0464
0465 static void dm_ebs_exit(void)
0466 {
0467 dm_unregister_target(&ebs_target);
0468 }
0469
0470 module_init(dm_ebs_init);
0471 module_exit(dm_ebs_exit);
0472
0473 MODULE_AUTHOR("Heinz Mauelshagen <dm-devel@redhat.com>");
0474 MODULE_DESCRIPTION(DM_NAME " emulated block size target");
0475 MODULE_LICENSE("GPL");