<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 18, 2019 at 4:04 AM Damien Le Moal <<a href="mailto:damien.lemoal@wdc.com">damien.lemoal@wdc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The function blkdev_report_zones() returns success even if no zone<br>
information is reported (empty report). Empty zone reports can only<br>
happen if the report start sector passed exceeds the device capacity.<br>
The conditions for this to happen are either a bug in the caller code,<br>
or, a change in the device that forced the low level driver to change<br>
the device capacity to a value that is lower than the report start<br>
sector. This situation includes a failed disk revalidation resulting in<br>
the disk capacity being changed to 0.<br>
<br>
If this change happens while dm-zoned is in its initialization phase<br>
executing dmz_init_zones(), this function may enter an infinite loop<br>
and hang the system. To avoid this, add a check to disallow empty zone<br>
reports and bail out early. Also fix the function dmz_update_zone() to<br>
make sure that the report for the requested zone was correctly obtained.<br>
<br>
Fixes: 3b1a94c88b79 ("dm zoned: drive-managed zoned block device target")<br>
Cc: <a href="mailto:stable@vger.kernel.org" target="_blank">stable@vger.kernel.org</a><br>
Signed-off-by: Damien Le Moal <<a href="mailto:damien.lemoal@wdc.com" target="_blank">damien.lemoal@wdc.com</a>><br>
---<br>
 drivers/md/dm-zoned-metadata.c | 5 +++++<br>
 1 file changed, 5 insertions(+)<br>
<br>
diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c<br>
index fa68336560c3..d8334cd45d7c 100644<br>
--- a/drivers/md/dm-zoned-metadata.c<br>
+++ b/drivers/md/dm-zoned-metadata.c<br>
@@ -1169,6 +1169,9 @@ static int dmz_init_zones(struct dmz_metadata *zmd)<br>
                        goto out;<br>
                }<br>
<br>
+               if (!nr_blkz)<br>
+                       break;<br>
+<br>
                /* Process report */<br>
                for (i = 0; i < nr_blkz; i++) {<br>
                        ret = dmz_init_zone(zmd, zone, &blkz[i]);<br>
@@ -1204,6 +1207,8 @@ static int dmz_update_zone(struct dmz_metadata *zmd, struct dm_zone *zone)<br>
        /* Get zone information from disk */<br>
        ret = blkdev_report_zones(zmd->dev->bdev, dmz_start_sect(zmd, zone),<br>
                                  &blkz, &nr_blkz, GFP_NOIO);<br>
+       if (!nr_blkz)<br>
+               ret = -EIO;<br>
        if (ret) {<br>
                dmz_dev_err(zmd->dev, "Get zone %u report failed",<br>
                            dmz_id(zmd, zone));<br></blockquote><div><br></div><div>Reviewed-by: Shaun Tancheff <<a href="mailto:shaun@tancheff.com">shaun@tancheff.com</a>></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-- <br>
2.20.1<br>
<br>
--<br>
dm-devel mailing list<br>
<a href="mailto:dm-devel@redhat.com" target="_blank">dm-devel@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/dm-devel" rel="noreferrer" target="_blank">https://www.redhat.com/mailman/listinfo/dm-devel</a><br>
</blockquote></div></div>