forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dm: move zone related code to dm-zone.c
Move core and table code used for zoned targets and conditionally defined with #ifdef CONFIG_BLK_DEV_ZONED to the new file dm-zone.c. This file is conditionally compiled depending on CONFIG_BLK_DEV_ZONED. The small helper dm_set_zones_restrictions() is introduced to initialize a mapped device request queue zone attributes in dm_table_set_restrictions(). Signed-off-by: Damien Le Moal <[email protected]> Reviewed-by: Johannes Thumshirn <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Himanshu Madhani <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
- Loading branch information
1 parent
dd73c32
commit 7fc1872
Showing
5 changed files
with
119 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2021 Western Digital Corporation or its affiliates. | ||
*/ | ||
|
||
#include <linux/blkdev.h> | ||
|
||
#include "dm-core.h" | ||
|
||
/* | ||
* User facing dm device block device report zone operation. This calls the | ||
* report_zones operation for each target of a device table. This operation is | ||
* generally implemented by targets using dm_report_zones(). | ||
*/ | ||
int dm_blk_report_zones(struct gendisk *disk, sector_t sector, | ||
unsigned int nr_zones, report_zones_cb cb, void *data) | ||
{ | ||
struct mapped_device *md = disk->private_data; | ||
struct dm_table *map; | ||
int srcu_idx, ret; | ||
struct dm_report_zones_args args = { | ||
.next_sector = sector, | ||
.orig_data = data, | ||
.orig_cb = cb, | ||
}; | ||
|
||
if (dm_suspended_md(md)) | ||
return -EAGAIN; | ||
|
||
map = dm_get_live_table(md, &srcu_idx); | ||
if (!map) { | ||
ret = -EIO; | ||
goto out; | ||
} | ||
|
||
do { | ||
struct dm_target *tgt; | ||
|
||
tgt = dm_table_find_target(map, args.next_sector); | ||
if (WARN_ON_ONCE(!tgt->type->report_zones)) { | ||
ret = -EIO; | ||
goto out; | ||
} | ||
|
||
args.tgt = tgt; | ||
ret = tgt->type->report_zones(tgt, &args, | ||
nr_zones - args.zone_idx); | ||
if (ret < 0) | ||
goto out; | ||
} while (args.zone_idx < nr_zones && | ||
args.next_sector < get_capacity(disk)); | ||
|
||
ret = args.zone_idx; | ||
out: | ||
dm_put_live_table(md, srcu_idx); | ||
return ret; | ||
} | ||
|
||
int dm_report_zones_cb(struct blk_zone *zone, unsigned int idx, void *data) | ||
{ | ||
struct dm_report_zones_args *args = data; | ||
sector_t sector_diff = args->tgt->begin - args->start; | ||
|
||
/* | ||
* Ignore zones beyond the target range. | ||
*/ | ||
if (zone->start >= args->start + args->tgt->len) | ||
return 0; | ||
|
||
/* | ||
* Remap the start sector and write pointer position of the zone | ||
* to match its position in the target range. | ||
*/ | ||
zone->start += sector_diff; | ||
if (zone->type != BLK_ZONE_TYPE_CONVENTIONAL) { | ||
if (zone->cond == BLK_ZONE_COND_FULL) | ||
zone->wp = zone->start + zone->len; | ||
else if (zone->cond == BLK_ZONE_COND_EMPTY) | ||
zone->wp = zone->start; | ||
else | ||
zone->wp += sector_diff; | ||
} | ||
|
||
args->next_sector = zone->start + zone->len; | ||
return args->orig_cb(zone, args->zone_idx++, args->orig_data); | ||
} | ||
EXPORT_SYMBOL_GPL(dm_report_zones_cb); | ||
|
||
void dm_set_zones_restrictions(struct dm_table *t, struct request_queue *q) | ||
{ | ||
if (!blk_queue_is_zoned(q)) | ||
return; | ||
|
||
/* | ||
* For a zoned target, the number of zones should be updated for the | ||
* correct value to be exposed in sysfs queue/nr_zones. For a BIO based | ||
* target, this is all that is needed. | ||
*/ | ||
WARN_ON_ONCE(queue_is_mq(q)); | ||
q->nr_zones = blkdev_nr_zones(t->md->disk); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters