Skip to content

Commit

Permalink
block: Fix partition support for host aware zoned block devices
Browse files Browse the repository at this point in the history
Commit b720530 ("block: allow partitions on host aware zone
devices") introduced the helper function disk_has_partitions() to check
if a given disk has valid partitions. However, since this function result
directly depends on the disk partition table length rather than the
actual existence of valid partitions in the table, it returns true even
after all partitions are removed from the disk. For host aware zoned
block devices, this results in zone management support to be kept
disabled even after removing all partitions.

Fix this by changing disk_has_partitions() to walk through the partition
table entries and return true if and only if a valid non-zero size
partition is found.

Fixes: b720530 ("block: allow partitions on host aware zone devices")
Cc: [email protected] # 5.5
Reviewed-by: Damien Le Moal <[email protected]>
Reviewed-by: Johannes Thumshirn <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Shin'ichiro Kawasaki <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
kawasaki authored and axboe committed Mar 12, 2020
1 parent cc3200e commit b53df2e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
36 changes: 36 additions & 0 deletions block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,42 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
}
EXPORT_SYMBOL_GPL(disk_map_sector_rcu);

/**
* disk_has_partitions
* @disk: gendisk of interest
*
* Walk through the partition table and check if valid partition exists.
*
* CONTEXT:
* Don't care.
*
* RETURNS:
* True if the gendisk has at least one valid non-zero size partition.
* Otherwise false.
*/
bool disk_has_partitions(struct gendisk *disk)
{
struct disk_part_tbl *ptbl;
int i;
bool ret = false;

rcu_read_lock();
ptbl = rcu_dereference(disk->part_tbl);

/* Iterate partitions skipping the whole device at index 0 */
for (i = 1; i < ptbl->len; i++) {
if (rcu_dereference(ptbl->part[i])) {
ret = true;
break;
}
}

rcu_read_unlock();

return ret;
}
EXPORT_SYMBOL_GPL(disk_has_partitions);

/*
* Can be deleted altogether. Later.
*
Expand Down
13 changes: 1 addition & 12 deletions include/linux/genhd.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,18 +245,6 @@ static inline bool disk_part_scan_enabled(struct gendisk *disk)
!(disk->flags & GENHD_FL_NO_PART_SCAN);
}

static inline bool disk_has_partitions(struct gendisk *disk)
{
bool ret = false;

rcu_read_lock();
if (rcu_dereference(disk->part_tbl)->len > 1)
ret = true;
rcu_read_unlock();

return ret;
}

static inline dev_t disk_devt(struct gendisk *disk)
{
return MKDEV(disk->major, disk->first_minor);
Expand Down Expand Up @@ -298,6 +286,7 @@ extern void disk_part_iter_exit(struct disk_part_iter *piter);

extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk,
sector_t sector);
bool disk_has_partitions(struct gendisk *disk);

/*
* Macros to operate on percpu disk statistics:
Expand Down

0 comments on commit b53df2e

Please sign in to comment.