dm.c (5eac3eb30c9ab9ee7fe2bd9aa9db6373cabb77f8) | dm.c (d41003513e61dd9d4974cb441d30b63650b85654) |
---|---|
1/* 2 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. 3 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm-core.h" --- 426 unchanged lines hidden (view full) --- 435 436static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) 437{ 438 struct mapped_device *md = bdev->bd_disk->private_data; 439 440 return dm_get_geometry(md, geo); 441} 442 | 1/* 2 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. 3 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm-core.h" --- 426 unchanged lines hidden (view full) --- 435 436static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) 437{ 438 struct mapped_device *md = bdev->bd_disk->private_data; 439 440 return dm_get_geometry(md, geo); 441} 442 |
443#ifdef CONFIG_BLK_DEV_ZONED 444int dm_report_zones_cb(struct blk_zone *zone, unsigned int idx, void *data) 445{ 446 struct dm_report_zones_args *args = data; 447 sector_t sector_diff = args->tgt->begin - args->start; 448 449 /* 450 * Ignore zones beyond the target range. 451 */ 452 if (zone->start >= args->start + args->tgt->len) 453 return 0; 454 455 /* 456 * Remap the start sector and write pointer position of the zone 457 * to match its position in the target range. 458 */ 459 zone->start += sector_diff; 460 if (zone->type != BLK_ZONE_TYPE_CONVENTIONAL) { 461 if (zone->cond == BLK_ZONE_COND_FULL) 462 zone->wp = zone->start + zone->len; 463 else if (zone->cond == BLK_ZONE_COND_EMPTY) 464 zone->wp = zone->start; 465 else 466 zone->wp += sector_diff; 467 } 468 469 args->next_sector = zone->start + zone->len; 470 return args->orig_cb(zone, args->zone_idx++, args->orig_data); 471} 472EXPORT_SYMBOL_GPL(dm_report_zones_cb); 473 |
|
443static int dm_blk_report_zones(struct gendisk *disk, sector_t sector, | 474static int dm_blk_report_zones(struct gendisk *disk, sector_t sector, |
444 struct blk_zone *zones, unsigned int *nr_zones) | 475 unsigned int nr_zones, report_zones_cb cb, void *data) |
445{ | 476{ |
446#ifdef CONFIG_BLK_DEV_ZONED | |
447 struct mapped_device *md = disk->private_data; | 477 struct mapped_device *md = disk->private_data; |
448 struct dm_target *tgt; | |
449 struct dm_table *map; 450 int srcu_idx, ret; | 478 struct dm_table *map; 479 int srcu_idx, ret; |
480 struct dm_report_zones_args args = { 481 .next_sector = sector, 482 .orig_data = data, 483 .orig_cb = cb, 484 }; |
|
451 452 if (dm_suspended_md(md)) 453 return -EAGAIN; 454 455 map = dm_get_live_table(md, &srcu_idx); 456 if (!map) 457 return -EIO; 458 | 485 486 if (dm_suspended_md(md)) 487 return -EAGAIN; 488 489 map = dm_get_live_table(md, &srcu_idx); 490 if (!map) 491 return -EIO; 492 |
459 tgt = dm_table_find_target(map, sector); 460 if (!tgt) { 461 ret = -EIO; 462 goto out; 463 } | 493 do { 494 struct dm_target *tgt; |
464 | 495 |
465 /* 466 * If we are executing this, we already know that the block device 467 * is a zoned device and so each target should have support for that 468 * type of drive. A missing report_zones method means that the target 469 * driver has a problem. 470 */ 471 if (WARN_ON(!tgt->type->report_zones)) { 472 ret = -EIO; 473 goto out; 474 } | 496 tgt = dm_table_find_target(map, args.next_sector); 497 if (WARN_ON_ONCE(!tgt->type->report_zones)) { 498 ret = -EIO; 499 goto out; 500 } |
475 | 501 |
476 ret = tgt->type->report_zones(tgt, sector, zones, nr_zones); | 502 args.tgt = tgt; 503 ret = tgt->type->report_zones(tgt, &args, nr_zones); 504 if (ret < 0) 505 goto out; 506 } while (args.zone_idx < nr_zones && 507 args.next_sector < get_capacity(disk)); |
477 | 508 |
509 ret = args.zone_idx; |
|
478out: 479 dm_put_live_table(md, srcu_idx); 480 return ret; | 510out: 511 dm_put_live_table(md, srcu_idx); 512 return ret; |
481#else 482 return -ENOTSUPP; 483#endif | |
484} | 513} |
514#else 515#define dm_blk_report_zones NULL 516#endif /* CONFIG_BLK_DEV_ZONED */ |
|
485 486static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx, 487 struct block_device **bdev) 488 __acquires(md->io_barrier) 489{ 490 struct dm_target *tgt; 491 struct dm_table *map; 492 int r; --- 709 unchanged lines hidden (view full) --- 1202 BUG_ON(bio->bi_opf & REQ_PREFLUSH); 1203 BUG_ON(bi_size > *tio->len_ptr); 1204 BUG_ON(n_sectors > bi_size); 1205 *tio->len_ptr -= bi_size - n_sectors; 1206 bio->bi_iter.bi_size = n_sectors << SECTOR_SHIFT; 1207} 1208EXPORT_SYMBOL_GPL(dm_accept_partial_bio); 1209 | 517 518static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx, 519 struct block_device **bdev) 520 __acquires(md->io_barrier) 521{ 522 struct dm_target *tgt; 523 struct dm_table *map; 524 int r; --- 709 unchanged lines hidden (view full) --- 1234 BUG_ON(bio->bi_opf & REQ_PREFLUSH); 1235 BUG_ON(bi_size > *tio->len_ptr); 1236 BUG_ON(n_sectors > bi_size); 1237 *tio->len_ptr -= bi_size - n_sectors; 1238 bio->bi_iter.bi_size = n_sectors << SECTOR_SHIFT; 1239} 1240EXPORT_SYMBOL_GPL(dm_accept_partial_bio); 1241 |
1210/* 1211 * The zone descriptors obtained with a zone report indicate 1212 * zone positions within the underlying device of the target. The zone 1213 * descriptors must be remapped to match their position within the dm device. 1214 */ 1215void dm_remap_zone_report(struct dm_target *ti, sector_t start, 1216 struct blk_zone *zones, unsigned int *nr_zones) 1217{ 1218#ifdef CONFIG_BLK_DEV_ZONED 1219 struct blk_zone *zone; 1220 unsigned int nrz = *nr_zones; 1221 int i; 1222 1223 /* 1224 * Remap the start sector and write pointer position of the zones in 1225 * the array. Since we may have obtained from the target underlying 1226 * device more zones that the target size, also adjust the number 1227 * of zones. 1228 */ 1229 for (i = 0; i < nrz; i++) { 1230 zone = zones + i; 1231 if (zone->start >= start + ti->len) { 1232 memset(zone, 0, sizeof(struct blk_zone) * (nrz - i)); 1233 break; 1234 } 1235 1236 zone->start = zone->start + ti->begin - start; 1237 if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) 1238 continue; 1239 1240 if (zone->cond == BLK_ZONE_COND_FULL) 1241 zone->wp = zone->start + zone->len; 1242 else if (zone->cond == BLK_ZONE_COND_EMPTY) 1243 zone->wp = zone->start; 1244 else 1245 zone->wp = zone->wp + ti->begin - start; 1246 } 1247 1248 *nr_zones = i; 1249#else /* !CONFIG_BLK_DEV_ZONED */ 1250 *nr_zones = 0; 1251#endif 1252} 1253EXPORT_SYMBOL_GPL(dm_remap_zone_report); 1254 | |
1255static blk_qc_t __map_bio(struct dm_target_io *tio) 1256{ 1257 int r; 1258 sector_t sector; 1259 struct bio *clone = &tio->clone; 1260 struct dm_io *io = tio->io; 1261 struct mapped_device *md = io->md; 1262 struct dm_target *ti = tio->ti; --- 1967 unchanged lines hidden --- | 1242static blk_qc_t __map_bio(struct dm_target_io *tio) 1243{ 1244 int r; 1245 sector_t sector; 1246 struct bio *clone = &tio->clone; 1247 struct dm_io *io = tio->io; 1248 struct mapped_device *md = io->md; 1249 struct dm_target *ti = tio->ti; --- 1967 unchanged lines hidden --- |