dm.c (6842d264aa5205da338b6dcc6acfa2a6732558f1) dm.c (7fc18728482b1a29bd7b8439a0ae7b3f23e097d1)
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"

--- 430 unchanged lines hidden (view full) ---

439
440static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
441{
442 struct mapped_device *md = bdev->bd_disk->private_data;
443
444 return dm_get_geometry(md, geo);
445}
446
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"

--- 430 unchanged lines hidden (view full) ---

439
440static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
441{
442 struct mapped_device *md = bdev->bd_disk->private_data;
443
444 return dm_get_geometry(md, geo);
445}
446
447#ifdef CONFIG_BLK_DEV_ZONED
448int dm_report_zones_cb(struct blk_zone *zone, unsigned int idx, void *data)
449{
450 struct dm_report_zones_args *args = data;
451 sector_t sector_diff = args->tgt->begin - args->start;
452
453 /*
454 * Ignore zones beyond the target range.
455 */
456 if (zone->start >= args->start + args->tgt->len)
457 return 0;
458
459 /*
460 * Remap the start sector and write pointer position of the zone
461 * to match its position in the target range.
462 */
463 zone->start += sector_diff;
464 if (zone->type != BLK_ZONE_TYPE_CONVENTIONAL) {
465 if (zone->cond == BLK_ZONE_COND_FULL)
466 zone->wp = zone->start + zone->len;
467 else if (zone->cond == BLK_ZONE_COND_EMPTY)
468 zone->wp = zone->start;
469 else
470 zone->wp += sector_diff;
471 }
472
473 args->next_sector = zone->start + zone->len;
474 return args->orig_cb(zone, args->zone_idx++, args->orig_data);
475}
476EXPORT_SYMBOL_GPL(dm_report_zones_cb);
477
478static int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
479 unsigned int nr_zones, report_zones_cb cb, void *data)
480{
481 struct mapped_device *md = disk->private_data;
482 struct dm_table *map;
483 int srcu_idx, ret;
484 struct dm_report_zones_args args = {
485 .next_sector = sector,
486 .orig_data = data,
487 .orig_cb = cb,
488 };
489
490 if (dm_suspended_md(md))
491 return -EAGAIN;
492
493 map = dm_get_live_table(md, &srcu_idx);
494 if (!map) {
495 ret = -EIO;
496 goto out;
497 }
498
499 do {
500 struct dm_target *tgt;
501
502 tgt = dm_table_find_target(map, args.next_sector);
503 if (WARN_ON_ONCE(!tgt->type->report_zones)) {
504 ret = -EIO;
505 goto out;
506 }
507
508 args.tgt = tgt;
509 ret = tgt->type->report_zones(tgt, &args,
510 nr_zones - args.zone_idx);
511 if (ret < 0)
512 goto out;
513 } while (args.zone_idx < nr_zones &&
514 args.next_sector < get_capacity(disk));
515
516 ret = args.zone_idx;
517out:
518 dm_put_live_table(md, srcu_idx);
519 return ret;
520}
521#else
522#define dm_blk_report_zones NULL
523#endif /* CONFIG_BLK_DEV_ZONED */
524
525static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx,
526 struct block_device **bdev)
527{
528 struct dm_target *tgt;
529 struct dm_table *map;
530 int r;
531
532retry:

--- 2652 unchanged lines hidden ---
447static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx,
448 struct block_device **bdev)
449{
450 struct dm_target *tgt;
451 struct dm_table *map;
452 int r;
453
454retry:

--- 2652 unchanged lines hidden ---