Merge tag 'lazytime_for_v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / block / blk-settings.c
index 43990b1..7dd8be3 100644 (file)
@@ -60,6 +60,7 @@ void blk_set_default_limits(struct queue_limits *lim)
        lim->io_opt = 0;
        lim->misaligned = 0;
        lim->zoned = BLK_ZONED_NONE;
+       lim->zone_write_granularity = 0;
 }
 EXPORT_SYMBOL(blk_set_default_limits);
 
@@ -366,6 +367,28 @@ void blk_queue_physical_block_size(struct request_queue *q, unsigned int size)
 }
 EXPORT_SYMBOL(blk_queue_physical_block_size);
 
+/**
+ * blk_queue_zone_write_granularity - set zone write granularity for the queue
+ * @q:  the request queue for the zoned device
+ * @size:  the zone write granularity size, in bytes
+ *
+ * Description:
+ *   This should be set to the lowest possible size allowing to write in
+ *   sequential zones of a zoned block device.
+ */
+void blk_queue_zone_write_granularity(struct request_queue *q,
+                                     unsigned int size)
+{
+       if (WARN_ON_ONCE(!blk_queue_is_zoned(q)))
+               return;
+
+       q->limits.zone_write_granularity = size;
+
+       if (q->limits.zone_write_granularity < q->limits.logical_block_size)
+               q->limits.zone_write_granularity = q->limits.logical_block_size;
+}
+EXPORT_SYMBOL_GPL(blk_queue_zone_write_granularity);
+
 /**
  * blk_queue_alignment_offset - set physical block alignment offset
  * @q: the request queue for the device
@@ -631,6 +654,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
                        t->discard_granularity;
        }
 
+       t->zone_write_granularity = max(t->zone_write_granularity,
+                                       b->zone_write_granularity);
        t->zoned = max(t->zoned, b->zoned);
        return ret;
 }
@@ -847,6 +872,8 @@ EXPORT_SYMBOL_GPL(blk_queue_can_use_dma_map_merging);
  */
 void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model)
 {
+       struct request_queue *q = disk->queue;
+
        switch (model) {
        case BLK_ZONED_HM:
                /*
@@ -865,7 +892,7 @@ void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model)
                 * we do nothing special as far as the block layer is concerned.
                 */
                if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) ||
-                   disk_has_partitions(disk))
+                   !xa_empty(&disk->part_tbl))
                        model = BLK_ZONED_NONE;
                break;
        case BLK_ZONED_NONE:
@@ -875,7 +902,17 @@ void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model)
                break;
        }
 
-       disk->queue->limits.zoned = model;
+       q->limits.zoned = model;
+       if (model != BLK_ZONED_NONE) {
+               /*
+                * Set the zone write granularity to the device logical block
+                * size by default. The driver can change this value if needed.
+                */
+               blk_queue_zone_write_granularity(q,
+                                               queue_logical_block_size(q));
+       } else {
+               blk_queue_clear_zone_settings(q);
+       }
 }
 EXPORT_SYMBOL_GPL(blk_queue_set_zoned);