Skip to content

Commit 9dbca16

Browse files
committed
Merge tag 'block-5.5-2020-01-26' of git://git.kernel.dk/linux-block
Pull block fix from Jens Axboe: "Unfortunately this weekend we had a few last minute reports, one was for block. The partition disable for zoned devices was overly restrictive, it can work (and be supported) just fine for host-aware variants. Here's a fix ensuring that's the case so we don't break existing users of that" * tag 'block-5.5-2020-01-26' of git://git.kernel.dk/linux-block: block: allow partitions on host aware zone devices
2 parents 54343d9 + b720530 commit 9dbca16

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

block/partition-generic.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,24 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
321321
const char *dname;
322322
int err;
323323

324+
/*
325+
* Partitions are not supported on zoned block devices that are used as
326+
* such.
327+
*/
328+
switch (disk->queue->limits.zoned) {
329+
case BLK_ZONED_HM:
330+
pr_warn("%s: partitions not supported on host managed zoned block device\n",
331+
disk->disk_name);
332+
return ERR_PTR(-ENXIO);
333+
case BLK_ZONED_HA:
334+
pr_info("%s: disabling host aware zoned block device support due to partitions\n",
335+
disk->disk_name);
336+
disk->queue->limits.zoned = BLK_ZONED_NONE;
337+
break;
338+
case BLK_ZONED_NONE:
339+
break;
340+
}
341+
324342
err = disk_expand_part_tbl(disk, partno);
325343
if (err)
326344
return ERR_PTR(err);
@@ -501,7 +519,7 @@ static bool blk_add_partition(struct gendisk *disk, struct block_device *bdev,
501519

502520
part = add_partition(disk, p, from, size, state->parts[p].flags,
503521
&state->parts[p].info);
504-
if (IS_ERR(part)) {
522+
if (IS_ERR(part) && PTR_ERR(part) != -ENXIO) {
505523
printk(KERN_ERR " %s: p%d could not be added: %ld\n",
506524
disk->disk_name, p, -PTR_ERR(part));
507525
return true;
@@ -540,10 +558,10 @@ int blk_add_partitions(struct gendisk *disk, struct block_device *bdev)
540558
}
541559

542560
/*
543-
* Partitions are not supported on zoned block devices.
561+
* Partitions are not supported on host managed zoned block devices.
544562
*/
545-
if (bdev_is_zoned(bdev)) {
546-
pr_warn("%s: ignoring partition table on zoned block device\n",
563+
if (disk->queue->limits.zoned == BLK_ZONED_HM) {
564+
pr_warn("%s: ignoring partition table on host managed zoned block device\n",
547565
disk->disk_name);
548566
ret = 0;
549567
goto out_free_state;

drivers/scsi/sd.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2958,15 +2958,16 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
29582958
q->limits.zoned = BLK_ZONED_HM;
29592959
} else {
29602960
sdkp->zoned = (buffer[8] >> 4) & 3;
2961-
if (sdkp->zoned == 1)
2961+
if (sdkp->zoned == 1 && !disk_has_partitions(sdkp->disk)) {
29622962
/* Host-aware */
29632963
q->limits.zoned = BLK_ZONED_HA;
2964-
else
2964+
} else {
29652965
/*
2966-
* Treat drive-managed devices as
2967-
* regular block devices.
2966+
* Treat drive-managed devices and host-aware devices
2967+
* with partitions as regular block devices.
29682968
*/
29692969
q->limits.zoned = BLK_ZONED_NONE;
2970+
}
29702971
}
29712972
if (blk_queue_is_zoned(q) && sdkp->first_scan)
29722973
sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n",

include/linux/genhd.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,18 @@ 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+
248260
static inline dev_t disk_devt(struct gendisk *disk)
249261
{
250262
return MKDEV(disk->major, disk->first_minor);

0 commit comments

Comments
 (0)