Skip to content

Commit b53df2e

Browse files
kawasakiaxboe
authored andcommitted
block: Fix partition support for host aware zoned block devices
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]>
1 parent cc3200e commit b53df2e

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

block/genhd.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,42 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector)
301301
}
302302
EXPORT_SYMBOL_GPL(disk_map_sector_rcu);
303303

304+
/**
305+
* disk_has_partitions
306+
* @disk: gendisk of interest
307+
*
308+
* Walk through the partition table and check if valid partition exists.
309+
*
310+
* CONTEXT:
311+
* Don't care.
312+
*
313+
* RETURNS:
314+
* True if the gendisk has at least one valid non-zero size partition.
315+
* Otherwise false.
316+
*/
317+
bool disk_has_partitions(struct gendisk *disk)
318+
{
319+
struct disk_part_tbl *ptbl;
320+
int i;
321+
bool ret = false;
322+
323+
rcu_read_lock();
324+
ptbl = rcu_dereference(disk->part_tbl);
325+
326+
/* Iterate partitions skipping the whole device at index 0 */
327+
for (i = 1; i < ptbl->len; i++) {
328+
if (rcu_dereference(ptbl->part[i])) {
329+
ret = true;
330+
break;
331+
}
332+
}
333+
334+
rcu_read_unlock();
335+
336+
return ret;
337+
}
338+
EXPORT_SYMBOL_GPL(disk_has_partitions);
339+
304340
/*
305341
* Can be deleted altogether. Later.
306342
*

include/linux/genhd.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,18 +245,6 @@ static inline bool disk_part_scan_enabled(struct gendisk *disk)
245245
!(disk->flags & GENHD_FL_NO_PART_SCAN);
246246
}
247247

248-
static inline bool disk_has_partitions(struct gendisk *disk)
249-
{
250-
bool ret = false;
251-
252-
rcu_read_lock();
253-
if (rcu_dereference(disk->part_tbl)->len > 1)
254-
ret = true;
255-
rcu_read_unlock();
256-
257-
return ret;
258-
}
259-
260248
static inline dev_t disk_devt(struct gendisk *disk)
261249
{
262250
return MKDEV(disk->major, disk->first_minor);
@@ -298,6 +286,7 @@ extern void disk_part_iter_exit(struct disk_part_iter *piter);
298286

299287
extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk,
300288
sector_t sector);
289+
bool disk_has_partitions(struct gendisk *disk);
301290

302291
/*
303292
* Macros to operate on percpu disk statistics:

0 commit comments

Comments
 (0)