@@ -1656,6 +1656,74 @@ static int disk_update_zone_resources(struct gendisk *disk,
16561656 return queue_limits_commit_update (q , & lim );
16571657}
16581658
1659+ static int blk_revalidate_conv_zone (struct blk_zone * zone , unsigned int idx ,
1660+ struct blk_revalidate_zone_args * args )
1661+ {
1662+ struct gendisk * disk = args -> disk ;
1663+ struct request_queue * q = disk -> queue ;
1664+
1665+ if (zone -> capacity != zone -> len ) {
1666+ pr_warn ("%s: Invalid conventional zone capacity\n" ,
1667+ disk -> disk_name );
1668+ return - ENODEV ;
1669+ }
1670+
1671+ if (!disk_need_zone_resources (disk ))
1672+ return 0 ;
1673+
1674+ if (!args -> conv_zones_bitmap ) {
1675+ args -> conv_zones_bitmap =
1676+ blk_alloc_zone_bitmap (q -> node , args -> nr_zones );
1677+ if (!args -> conv_zones_bitmap )
1678+ return - ENOMEM ;
1679+ }
1680+
1681+ set_bit (idx , args -> conv_zones_bitmap );
1682+
1683+ return 0 ;
1684+ }
1685+
1686+ static int blk_revalidate_seq_zone (struct blk_zone * zone , unsigned int idx ,
1687+ struct blk_revalidate_zone_args * args )
1688+ {
1689+ struct gendisk * disk = args -> disk ;
1690+ struct blk_zone_wplug * zwplug ;
1691+ unsigned int wp_offset ;
1692+ unsigned long flags ;
1693+
1694+ /*
1695+ * Remember the capacity of the first sequential zone and check
1696+ * if it is constant for all zones.
1697+ */
1698+ if (!args -> zone_capacity )
1699+ args -> zone_capacity = zone -> capacity ;
1700+ if (zone -> capacity != args -> zone_capacity ) {
1701+ pr_warn ("%s: Invalid variable zone capacity\n" ,
1702+ disk -> disk_name );
1703+ return - ENODEV ;
1704+ }
1705+
1706+ /*
1707+ * We need to track the write pointer of all zones that are not
1708+ * empty nor full. So make sure we have a zone write plug for
1709+ * such zone if the device has a zone write plug hash table.
1710+ */
1711+ if (!disk -> zone_wplugs_hash )
1712+ return 0 ;
1713+
1714+ wp_offset = blk_zone_wp_offset (zone );
1715+ if (!wp_offset || wp_offset >= zone -> capacity )
1716+ return 0 ;
1717+
1718+ zwplug = disk_get_and_lock_zone_wplug (disk , zone -> wp , GFP_NOIO , & flags );
1719+ if (!zwplug )
1720+ return - ENOMEM ;
1721+ spin_unlock_irqrestore (& zwplug -> lock , flags );
1722+ disk_put_zone_wplug (zwplug );
1723+
1724+ return 0 ;
1725+ }
1726+
16591727/*
16601728 * Helper function to check the validity of zones of a zoned block device.
16611729 */
@@ -1664,12 +1732,9 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
16641732{
16651733 struct blk_revalidate_zone_args * args = data ;
16661734 struct gendisk * disk = args -> disk ;
1667- struct request_queue * q = disk -> queue ;
16681735 sector_t capacity = get_capacity (disk );
1669- sector_t zone_sectors = q -> limits .chunk_sectors ;
1670- struct blk_zone_wplug * zwplug ;
1671- unsigned long flags ;
1672- unsigned int wp_offset ;
1736+ sector_t zone_sectors = disk -> queue -> limits .chunk_sectors ;
1737+ int ret ;
16731738
16741739 /* Check for bad zones and holes in the zone report */
16751740 if (zone -> start != args -> sector ) {
@@ -1709,62 +1774,22 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
17091774 /* Check zone type */
17101775 switch (zone -> type ) {
17111776 case BLK_ZONE_TYPE_CONVENTIONAL :
1712- if (zone -> capacity != zone -> len ) {
1713- pr_warn ("%s: Invalid conventional zone capacity\n" ,
1714- disk -> disk_name );
1715- return - ENODEV ;
1716- }
1717-
1718- if (!disk_need_zone_resources (disk ))
1719- break ;
1720- if (!args -> conv_zones_bitmap ) {
1721- args -> conv_zones_bitmap =
1722- blk_alloc_zone_bitmap (q -> node , args -> nr_zones );
1723- if (!args -> conv_zones_bitmap )
1724- return - ENOMEM ;
1725- }
1726- set_bit (idx , args -> conv_zones_bitmap );
1777+ ret = blk_revalidate_conv_zone (zone , idx , args );
17271778 break ;
17281779 case BLK_ZONE_TYPE_SEQWRITE_REQ :
1729- /*
1730- * Remember the capacity of the first sequential zone and check
1731- * if it is constant for all zones.
1732- */
1733- if (!args -> zone_capacity )
1734- args -> zone_capacity = zone -> capacity ;
1735- if (zone -> capacity != args -> zone_capacity ) {
1736- pr_warn ("%s: Invalid variable zone capacity\n" ,
1737- disk -> disk_name );
1738- return - ENODEV ;
1739- }
1740-
1741- /*
1742- * We need to track the write pointer of all zones that are not
1743- * empty nor full. So make sure we have a zone write plug for
1744- * such zone if the device has a zone write plug hash table.
1745- */
1746- if (!disk -> zone_wplugs_hash )
1747- break ;
1748- wp_offset = blk_zone_wp_offset (zone );
1749- if (wp_offset && wp_offset < zone -> capacity ) {
1750- zwplug = disk_get_and_lock_zone_wplug (disk , zone -> wp ,
1751- GFP_NOIO , & flags );
1752- if (!zwplug )
1753- return - ENOMEM ;
1754- spin_unlock_irqrestore (& zwplug -> lock , flags );
1755- disk_put_zone_wplug (zwplug );
1756- }
1757-
1780+ ret = blk_revalidate_seq_zone (zone , idx , args );
17581781 break ;
17591782 case BLK_ZONE_TYPE_SEQWRITE_PREF :
17601783 default :
17611784 pr_warn ("%s: Invalid zone type 0x%x at sectors %llu\n" ,
17621785 disk -> disk_name , (int )zone -> type , zone -> start );
1763- return - ENODEV ;
1786+ ret = - ENODEV ;
17641787 }
17651788
1766- args -> sector += zone -> len ;
1767- return 0 ;
1789+ if (!ret )
1790+ args -> sector += zone -> len ;
1791+
1792+ return ret ;
17681793}
17691794
17701795/**
0 commit comments