From patchwork Thu Apr 21 18:30:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 565591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CACB1C433F5 for ; Thu, 21 Apr 2022 18:30:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391367AbiDUSdb (ORCPT ); Thu, 21 Apr 2022 14:33:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391354AbiDUSd1 (ORCPT ); Thu, 21 Apr 2022 14:33:27 -0400 Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E66564BB80 for ; Thu, 21 Apr 2022 11:30:36 -0700 (PDT) Received: by mail-pf1-f169.google.com with SMTP id y14so4991354pfe.10 for ; Thu, 21 Apr 2022 11:30:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=K/cy4vL7n7xbQDxByfmcCwumO1cEnIuebqivcjkHRlw=; b=YM7M577CNdQ0y4ACPgXJ1XrFeAPSQvnLFm0hwqrYO1rxwfKLtHEnMD6NJm4ioJGPBw EvHth6P23XojiAu2ayVHN9bkvoradZmSDnKxtr0GXdqBvDoy6Wo2Op7RJbGYdf+diI2O JxFMibN9v8r+e1hTWf5sdiX2T9E/6GcQy2djrcfnI54vjvV38h4NcDPXnPaAOcHfDBiM DVLTggenY/0v3ieoskgZUdrwyTop345K2Mrb7CBnODJV7dzpWgWM8BbKeVQ1D0Aqn/C4 rry/q45Hf2S4RiU0AlGPhjxLuMx5si0rbRFkHMZ/XKwgHV1O89DtDpyBXFlwrobqrotp fEJQ== X-Gm-Message-State: AOAM530rn4a6qmEDRs35uN1ISb9JzA8Leiz6jTSsdFNeqTxmCVPPjI03 JGDbmDi10PdKpVr3w8n9DFk= X-Google-Smtp-Source: ABdhPJxt7sxs/Ab3OT6hlR2YjUt0A8oBhWwPxnmYXGz5e9nyXaq+0USFxAiQeY8FhVuKKI+idy7Cww== X-Received: by 2002:a05:6a00:22c4:b0:50a:63d9:f5b4 with SMTP id f4-20020a056a0022c400b0050a63d9f5b4mr947358pfj.80.1650565836301; Thu, 21 Apr 2022 11:30:36 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:35 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 1/9] scsi: sd_zbc: Improve source code documentation Date: Thu, 21 Apr 2022 11:30:15 -0700 Message-Id: <20220421183023.3462291-2-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Add several kernel-doc headers. Declare input arrays const. Specify the array size in function declarations. Reviewed-by: Damien Le Moal Signed-off-by: Bart Van Assche --- drivers/scsi/sd.h | 5 ++-- drivers/scsi/sd_zbc.c | 55 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 0a33a4b68ffb..4849cbe771a7 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -222,7 +222,7 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp) #ifdef CONFIG_BLK_DEV_ZONED void sd_zbc_release_disk(struct scsi_disk *sdkp); -int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer); +int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]); int sd_zbc_revalidate_zones(struct scsi_disk *sdkp); blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd, unsigned char op, bool all); @@ -238,8 +238,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, static inline void sd_zbc_release_disk(struct scsi_disk *sdkp) {} -static inline int sd_zbc_read_zones(struct scsi_disk *sdkp, - unsigned char *buf) +static inline int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) { return 0; } diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 7f466280993b..2ae44bc52a5f 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -20,6 +20,12 @@ #include "sd.h" +/** + * sd_zbc_get_zone_wp_offset - Get zone write pointer offset. + * @zone: Zone for which to return the write pointer offset. + * + * Return: offset of the write pointer from the start of the zone. + */ static unsigned int sd_zbc_get_zone_wp_offset(struct blk_zone *zone) { if (zone->type == ZBC_ZONE_TYPE_CONV) @@ -44,7 +50,21 @@ static unsigned int sd_zbc_get_zone_wp_offset(struct blk_zone *zone) } } -static int sd_zbc_parse_report(struct scsi_disk *sdkp, u8 *buf, +/** + * sd_zbc_parse_report - Parse a SCSI zone descriptor + * @sdkp: SCSI disk pointer. + * @buf: SCSI zone descriptor. + * @idx: Index of the zone relative to the first zone reported by the current + * sd_zbc_report_zones() call. + * @cb: Callback function pointer. + * @data: Second argument passed to @cb. + * + * Return: Value returned by @cb. + * + * Convert a SCSI zone descriptor into struct blk_zone format. Additionally, + * call @cb(blk_zone, @data). + */ +static int sd_zbc_parse_report(struct scsi_disk *sdkp, const u8 buf[64], unsigned int idx, report_zones_cb cb, void *data) { struct scsi_device *sdp = sdkp->device; @@ -189,6 +209,17 @@ static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp) return logical_to_sectors(sdkp->device, sdkp->zone_blocks); } +/** + * sd_zbc_report_zones - SCSI .report_zones() callback. + * @disk: Disk to report zones for. + * @sector: Start sector. + * @nr_zones: Maximum number of zones to report. + * @cb: Callback function called to report zone information. + * @data: Second argument passed to @cb. + * + * Called by the block layer to iterate over zone information. See also the + * disk->fops->report_zones() calls in block/blk-zoned.c. + */ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data) { @@ -276,6 +307,10 @@ static int sd_zbc_update_wp_offset_cb(struct blk_zone *zone, unsigned int idx, return 0; } +/* + * An attempt to append a zone triggered an invalid write pointer error. + * Reread the write pointer of the zone(s) in which the append failed. + */ static void sd_zbc_update_wp_offset_workfn(struct work_struct *work) { struct scsi_disk *sdkp; @@ -585,7 +620,7 @@ static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, * sd_zbc_check_capacity - Check the device capacity * @sdkp: Target disk * @buf: command buffer - * @zblocks: zone size in number of blocks + * @zblocks: zone size in logical blocks * * Get the device zone size and check that the device capacity as reported * by READ CAPACITY matches the max_lba value (plus one) of the report zones @@ -696,6 +731,11 @@ static void sd_zbc_revalidate_zones_cb(struct gendisk *disk) swap(sdkp->zones_wp_offset, sdkp->rev_wp_offset); } +/* + * Call blk_revalidate_disk_zones() if any of the zoned disk properties have + * changed that make it necessary to call that function. Called by + * sd_revalidate_disk() after the gendisk capacity has been set. + */ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) { struct gendisk *disk = sdkp->disk; @@ -774,7 +814,16 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) return ret; } -int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf) +/** + * sd_zbc_read_zones - Read zone information and update the request queue + * @sdkp: SCSI disk pointer. + * @buf: 512 byte buffer used for storing SCSI command output. + * + * Read zone information and update the request queue zone characteristics and + * also the zoned device information in *sdkp. Called by sd_revalidate_disk() + * before the gendisk capacity has been set. + */ +int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) { struct gendisk *disk = sdkp->disk; struct request_queue *q = disk->queue; From patchwork Thu Apr 21 18:30:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 564716 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50DEAC433F5 for ; Thu, 21 Apr 2022 18:30:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391374AbiDUSdi (ORCPT ); Thu, 21 Apr 2022 14:33:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242768AbiDUSd3 (ORCPT ); Thu, 21 Apr 2022 14:33:29 -0400 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C14CC4BB82 for ; Thu, 21 Apr 2022 11:30:38 -0700 (PDT) Received: by mail-pj1-f41.google.com with SMTP id iq10so1949418pjb.0 for ; Thu, 21 Apr 2022 11:30:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GOwCxOmcpg8qevQ4HBSE2TMzu2pCuWaDfQK1i23f80Y=; b=gsCx5wlR4PFH0ePcE3a2mMBFFQzzyUWPUjd4juYxEVXtGliNzdihxwOkU6x6bRzNNL 9CmQw6LKGo016qCKe6aaS42/16cKtAthYNpjI+JDl6yqniBzMiB7JTrqPRaAYdBDuDL9 CL2p1u6dgkJXQYBTHjmdlU//8lGV+S0W23RRW9Q2x5EHVP4aZTd3bpHZFtT67YHQy8/R G8lE7DY3K7j8nnB5xb8Y5cV6kpSrrnk8jlBm7+Ngg3sY7uIlV2cLrljayIcGUwC+EirF 8hE4VBtGYCSpwqbnt1gjQKQdicAEjCuLMA87oAbt36SbbKKBvYL/enMrOj+9iiFzf7ZQ zibg== X-Gm-Message-State: AOAM531LqF9jma8DIsDqf4+bHFT+ol6V9bf4+XRx+HFu8wlRA86uo6EP VIFyjRt+Dc9F1o6RHNSzwuM= X-Google-Smtp-Source: ABdhPJzqNZi3FYSHARX8xoNQcMLnycPjGgw8WzifO+KoLGNun5vait0saKoEoR+Itp5yzGcQBr5A0g== X-Received: by 2002:a17:90a:70cf:b0:1cb:a31e:a2c1 with SMTP id a15-20020a17090a70cf00b001cba31ea2c1mr11935978pjm.94.1650565838065; Thu, 21 Apr 2022 11:30:38 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:37 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 2/9] scsi: sd_zbc: Verify that the zone size is a power of two Date: Thu, 21 Apr 2022 11:30:16 -0700 Message-Id: <20220421183023.3462291-3-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The following check in sd_zbc_cmnd_checks() can only work correctly if the zone size is a power of two: if (sector & (sd_zbc_zone_sectors(sdkp) - 1)) /* Unaligned request */ return BLK_STS_IOERR; Hence this patch that verifies that the zone size is a power of two. Reviewed-by: Damien Le Moal Signed-off-by: Bart Van Assche Reviewed-by: Himanshu Madhani --- drivers/scsi/sd_zbc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 2ae44bc52a5f..9ef5ad345185 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -664,6 +664,13 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf, return -EFBIG; } + if (!is_power_of_2(zone_blocks)) { + sd_printk(KERN_ERR, sdkp, + "Zone size %llu is not a power of two.\n", + zone_blocks); + return -EINVAL; + } + *zblocks = zone_blocks; return 0; From patchwork Thu Apr 21 18:30:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 565590 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6A271C433EF for ; Thu, 21 Apr 2022 18:30:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391375AbiDUSdj (ORCPT ); Thu, 21 Apr 2022 14:33:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391366AbiDUSdb (ORCPT ); Thu, 21 Apr 2022 14:33:31 -0400 Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 872A64BB80 for ; Thu, 21 Apr 2022 11:30:40 -0700 (PDT) Received: by mail-pj1-f54.google.com with SMTP id j8-20020a17090a060800b001cd4fb60dccso5968977pjj.2 for ; Thu, 21 Apr 2022 11:30:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+ywR3IE+RqFTqhhoazuRftseC+YL/piARl7l7ozGdgw=; b=wcjtyKWqjipLzNZmwcob4mCxozEddAZkfQ607SROGg1SgeFer5fMNseX4IpyJwcZxV UGZP926V4T8R9OGYpdRBsfxteQ2DynnfRfCJXg9QBBD/zHBwoSFPXV3HR1BXMfVjVQ8/ PywyFTNKkKTFaVx0xp8YUQ4oI3sUDohry+TnX1OSNQgdwgISU9YJb/tSL42SKRKv8NHX K+RFs17jecESIXtx/uV6thESMb3Cbdlu8+IEtYyNY7+Wwmq+UuPipjJzIQIQc+XhNQvp 3vY7uSckyMSW91DvkfszY06n+XAxdbFWYZQWSNlm44Z64zrcpxMYzH/lYCeaaDunoT6D Wlwg== X-Gm-Message-State: AOAM532kJRaDoA9ZEFS4eowBmc5WQn7KYDWxldfwDTK/dv49dFIWQBbS cZOLIRev+2Pn/IS+ywF4LPA= X-Google-Smtp-Source: ABdhPJyP74pTX5pLIsKr2Zn4sS2D7vG67K615RiZwmmdFY38dAl/GYaskev4L/xcsOyYj+4SblTlKQ== X-Received: by 2002:a17:902:ce0a:b0:156:72e2:f191 with SMTP id k10-20020a170902ce0a00b0015672e2f191mr798126plg.76.1650565839993; Thu, 21 Apr 2022 11:30:39 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:39 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 3/9] scsi: sd_zbc: Use logical blocks as unit when querying zones Date: Thu, 21 Apr 2022 11:30:17 -0700 Message-Id: <20220421183023.3462291-4-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org When querying zones, track the position in logical blocks instead of in sectors. This change slightly simplifies sd_zbc_report_zones(). Signed-off-by: Damien Le Moal [ bvanassche: extracted this change from a larger patch ] Signed-off-by: Bart Van Assche --- drivers/scsi/sd_zbc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 9ef5ad345185..e76bcbfd0d1c 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -224,7 +224,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, unsigned int nr_zones, report_zones_cb cb, void *data) { struct scsi_disk *sdkp = scsi_disk(disk); - sector_t capacity = logical_to_sectors(sdkp->device, sdkp->capacity); + sector_t lba = sectors_to_logical(sdkp->device, sector); unsigned int nr, i; unsigned char *buf; size_t offset, buflen = 0; @@ -235,7 +235,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, /* Not a zoned device */ return -EOPNOTSUPP; - if (!capacity) + if (!sdkp->capacity) /* Device gone or invalid */ return -ENODEV; @@ -243,9 +243,8 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, if (!buf) return -ENOMEM; - while (zone_idx < nr_zones && sector < capacity) { - ret = sd_zbc_do_report_zones(sdkp, buf, buflen, - sectors_to_logical(sdkp->device, sector), true); + while (zone_idx < nr_zones && lba < sdkp->capacity) { + ret = sd_zbc_do_report_zones(sdkp, buf, buflen, lba, true); if (ret) goto out; @@ -263,7 +262,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, zone_idx++; } - sector += sd_zbc_zone_sectors(sdkp) * i; + lba += sdkp->zone_blocks * i; } ret = zone_idx; From patchwork Thu Apr 21 18:30:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 565589 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 181A8C433FE for ; Thu, 21 Apr 2022 18:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391388AbiDUSdn (ORCPT ); Thu, 21 Apr 2022 14:33:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391354AbiDUSdd (ORCPT ); Thu, 21 Apr 2022 14:33:33 -0400 Received: from mail-pj1-f44.google.com (mail-pj1-f44.google.com [209.85.216.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B672F4BB81 for ; Thu, 21 Apr 2022 11:30:42 -0700 (PDT) Received: by mail-pj1-f44.google.com with SMTP id d23-20020a17090a115700b001d2bde6c234so5950141pje.1 for ; Thu, 21 Apr 2022 11:30:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3sUcPhWk4UZGD/LCG+ymTIg5avupQuvVBZpeiA+1el0=; b=x9lScGjAtk+Qc+cD017u+/eNGJSCKKzWOpcUvl2Es+ycjcCsq1LIUu7wr5rhpUr9mh mTOQxc/nInGyXvqcBeBo9Tsgm5AZApwAR6fi1nUTb2U55hsFhS+IuNxkZAySUz+lOf4R dJR4Q1iWtZLDyrNRk10/LEqavZ/zeKkNVjZMSbYMeVec7KzFpAuMEm05hL9uXEvoToPK V9TY889Uump80mTTT6bx2KuPHs+wsW7jcEvf5khC7x6muZnCEx1LKTS/W02+2ftNIiMY NDEVfFUDQJkqsV8WAyoBGMOEP2SidygX6OAQzDzHsXV5dCXOkhQnaiqRRLXPrJln32I9 SrUQ== X-Gm-Message-State: AOAM530ykfb2/jtb6+5F+lde+waWJLc3IOKZ4otgeXtaa5U9ZbORguhC +jA54RoXORSobDFzofjZBHE= X-Google-Smtp-Source: ABdhPJy4pSeNdGInmM19S8zunnebz1MmYR3cdu17RFj429yO/uozMU74CMO2vkf4cxn85/sm92n2pw== X-Received: by 2002:a17:90a:7c04:b0:1d7:d7e6:2916 with SMTP id v4-20020a17090a7c0400b001d7d7e62916mr122636pjf.25.1650565841878; Thu, 21 Apr 2022 11:30:41 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:41 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 4/9] scsi: sd_zbc: Introduce struct zoned_disk_info Date: Thu, 21 Apr 2022 11:30:18 -0700 Message-Id: <20220421183023.3462291-5-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Deriving the meaning of the nr_zones, rev_nr_zones, zone_blocks and rev_zone_blocks member variables requires careful analysis of the source code. Make the meaning of these member variables easier to understand by introducing struct zoned_disk_info. Reviewed-by: Damien Le Moal Signed-off-by: Bart Van Assche --- drivers/scsi/sd.h | 22 +++++++++++++++---- drivers/scsi/sd_zbc.c | 49 ++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 4849cbe771a7..47434f905b0a 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -67,6 +67,20 @@ enum { SD_ZERO_WS10_UNMAP, /* Use WRITE SAME(10) with UNMAP */ }; +/** + * struct zoned_disk_info - Specific properties of a ZBC SCSI device. + * @nr_zones: number of zones. + * @zone_blocks: number of logical blocks per zone. + * + * This data structure holds the ZBC SCSI device properties that are retrieved + * twice: a first time before the gendisk capacity is known and a second time + * after the gendisk capacity is known. + */ +struct zoned_disk_info { + u32 nr_zones; + u32 zone_blocks; +}; + struct scsi_disk { struct scsi_device *device; @@ -78,10 +92,10 @@ struct scsi_disk { struct gendisk *disk; struct opal_dev *opal_dev; #ifdef CONFIG_BLK_DEV_ZONED - u32 nr_zones; - u32 rev_nr_zones; - u32 zone_blocks; - u32 rev_zone_blocks; + /* Updated during revalidation before the gendisk capacity is known. */ + struct zoned_disk_info early_zone_info; + /* Updated during revalidation after the gendisk capacity is known. */ + struct zoned_disk_info zone_info; u32 zones_optimal_open; u32 zones_optimal_nonseq; u32 zones_max_open; diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index e76bcbfd0d1c..ac557a5a65c8 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -181,7 +181,7 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, * sure that the allocated buffer can always be mapped by limiting the * number of pages allocated to the HBA max segments limit. */ - nr_zones = min(nr_zones, sdkp->nr_zones); + nr_zones = min(nr_zones, sdkp->zone_info.nr_zones); bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE); bufsize = min_t(size_t, bufsize, queue_max_hw_sectors(q) << SECTOR_SHIFT); @@ -206,7 +206,7 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, */ static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp) { - return logical_to_sectors(sdkp->device, sdkp->zone_blocks); + return logical_to_sectors(sdkp->device, sdkp->zone_info.zone_blocks); } /** @@ -262,7 +262,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, zone_idx++; } - lba += sdkp->zone_blocks * i; + lba += sdkp->zone_info.zone_blocks * i; } ret = zone_idx; @@ -320,14 +320,14 @@ static void sd_zbc_update_wp_offset_workfn(struct work_struct *work) sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); - for (zno = 0; zno < sdkp->nr_zones; zno++) { + for (zno = 0; zno < sdkp->zone_info.nr_zones; zno++) { if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) continue; spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); ret = sd_zbc_do_report_zones(sdkp, sdkp->zone_wp_update_buf, SD_BUF_SIZE, - zno * sdkp->zone_blocks, true); + zno * sdkp->zone_info.zone_blocks, true); spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); if (!ret) sd_zbc_parse_report(sdkp, sdkp->zone_wp_update_buf + 64, @@ -394,7 +394,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, break; default: wp_offset = sectors_to_logical(sdkp->device, wp_offset); - if (wp_offset + nr_blocks > sdkp->zone_blocks) { + if (wp_offset + nr_blocks > sdkp->zone_info.zone_blocks) { ret = BLK_STS_IOERR; break; } @@ -523,7 +523,7 @@ static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd, break; case REQ_OP_ZONE_RESET_ALL: memset(sdkp->zones_wp_offset, 0, - sdkp->nr_zones * sizeof(unsigned int)); + sdkp->zone_info.nr_zones * sizeof(unsigned int)); break; default: break; @@ -680,16 +680,16 @@ static void sd_zbc_print_zones(struct scsi_disk *sdkp) if (!sd_is_zoned(sdkp) || !sdkp->capacity) return; - if (sdkp->capacity & (sdkp->zone_blocks - 1)) + if (sdkp->capacity & (sdkp->zone_info.zone_blocks - 1)) sd_printk(KERN_NOTICE, sdkp, "%u zones of %u logical blocks + 1 runt zone\n", - sdkp->nr_zones - 1, - sdkp->zone_blocks); + sdkp->zone_info.nr_zones - 1, + sdkp->zone_info.zone_blocks); else sd_printk(KERN_NOTICE, sdkp, "%u zones of %u logical blocks\n", - sdkp->nr_zones, - sdkp->zone_blocks); + sdkp->zone_info.nr_zones, + sdkp->zone_info.zone_blocks); } static int sd_zbc_init_disk(struct scsi_disk *sdkp) @@ -716,10 +716,8 @@ static void sd_zbc_clear_zone_info(struct scsi_disk *sdkp) kfree(sdkp->zone_wp_update_buf); sdkp->zone_wp_update_buf = NULL; - sdkp->nr_zones = 0; - sdkp->rev_nr_zones = 0; - sdkp->zone_blocks = 0; - sdkp->rev_zone_blocks = 0; + sdkp->early_zone_info = (struct zoned_disk_info){ }; + sdkp->zone_info = (struct zoned_disk_info){ }; mutex_unlock(&sdkp->rev_mutex); } @@ -746,8 +744,8 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) { struct gendisk *disk = sdkp->disk; struct request_queue *q = disk->queue; - u32 zone_blocks = sdkp->rev_zone_blocks; - unsigned int nr_zones = sdkp->rev_nr_zones; + u32 zone_blocks = sdkp->early_zone_info.zone_blocks; + unsigned int nr_zones = sdkp->early_zone_info.nr_zones; u32 max_append; int ret = 0; unsigned int flags; @@ -778,14 +776,14 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) */ mutex_lock(&sdkp->rev_mutex); - if (sdkp->zone_blocks == zone_blocks && - sdkp->nr_zones == nr_zones && + if (sdkp->zone_info.zone_blocks == zone_blocks && + sdkp->zone_info.nr_zones == nr_zones && disk->queue->nr_zones == nr_zones) goto unlock; flags = memalloc_noio_save(); - sdkp->zone_blocks = zone_blocks; - sdkp->nr_zones = nr_zones; + sdkp->zone_info.zone_blocks = zone_blocks; + sdkp->zone_info.nr_zones = nr_zones; sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_KERNEL); if (!sdkp->rev_wp_offset) { ret = -ENOMEM; @@ -800,8 +798,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) sdkp->rev_wp_offset = NULL; if (ret) { - sdkp->zone_blocks = 0; - sdkp->nr_zones = 0; + sdkp->zone_info = (struct zoned_disk_info){ }; sdkp->capacity = 0; goto unlock; } @@ -887,8 +884,8 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) if (blk_queue_zoned_model(q) == BLK_ZONED_HM) blk_queue_zone_write_granularity(q, sdkp->physical_block_size); - sdkp->rev_nr_zones = nr_zones; - sdkp->rev_zone_blocks = zone_blocks; + sdkp->early_zone_info.nr_zones = nr_zones; + sdkp->early_zone_info.zone_blocks = zone_blocks; return 0; From patchwork Thu Apr 21 18:30:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 564715 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C379EC433F5 for ; Thu, 21 Apr 2022 18:30:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391383AbiDUSdl (ORCPT ); Thu, 21 Apr 2022 14:33:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391368AbiDUSde (ORCPT ); Thu, 21 Apr 2022 14:33:34 -0400 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2D32C4BB84 for ; Thu, 21 Apr 2022 11:30:44 -0700 (PDT) Received: by mail-pj1-f49.google.com with SMTP id md4so5694369pjb.4 for ; Thu, 21 Apr 2022 11:30:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IMaqiEmvW8IdKU81nnUqSEa/O3hGhvNCLFggqQwvW9g=; b=qTIO+R7934DAiPuiKdQS2mS/PLX54enJPPIdSTJG8LF/29OYaO8k2BQVHZuVd2B3mA mMa1VZzyyf5avvXAih7WW7VAQOP3UO746TY6R8jAlfgq36K9Ri9cyYWLi0m3vkGV1atW dCkjQfF9OhUUL/bYYTSz+WHmZTFn9VReEG327BOX4+GGvS3gxp0n+n01EvWpRS+1Yoam 5kltNNU61F39o6wV2kwfcF4hOmhBa9iJ8MlG7ADED7h4c+N4qcGSNilQxyN9tKo+dIBf vUFqZLBMfz2t6lQcMlyxix1Y7Cxif6RIEjjHyTWhjANATxoV93xPYKhJ8n2TnIqnlS3N 6Hiw== X-Gm-Message-State: AOAM532XOEy7Fc+4mZMkOkk5DKNk7/f50k7WhDgOk3AaXkydC0JIcYNX ZArlSN+C/HR25BTtxMQScmc= X-Google-Smtp-Source: ABdhPJyG4wtciLvv3+vFMI6YNIvQ8/E+PVB8gKsxEBaj5q9g4BOp/e/n5aU2zoLDu7PQTEfqaQQQwA== X-Received: by 2002:a17:90b:2691:b0:1d2:72b9:b9b with SMTP id pl17-20020a17090b269100b001d272b90b9bmr1062550pjb.80.1650565843628; Thu, 21 Apr 2022 11:30:43 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:42 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 5/9] scsi: sd_zbc: Return early in sd_zbc_check_zoned_characteristics() Date: Thu, 21 Apr 2022 11:30:19 -0700 Message-Id: <20220421183023.3462291-6-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Return early in sd_zbc_check_zoned_characteristics() for host-aware disks. This patch does not change any functionality but makes a later patch easier to read. Signed-off-by: Damien Le Moal [ bvanassche: extracted this change from a larger patch ] Signed-off-by: Bart Van Assche --- drivers/scsi/sd_zbc.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index ac557a5a65c8..c53e166362b9 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -592,14 +592,15 @@ static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, sdkp->zones_optimal_open = get_unaligned_be32(&buf[8]); sdkp->zones_optimal_nonseq = get_unaligned_be32(&buf[12]); sdkp->zones_max_open = 0; - } else { - /* Host-managed */ - sdkp->urswrz = buf[4] & 1; - sdkp->zones_optimal_open = 0; - sdkp->zones_optimal_nonseq = 0; - sdkp->zones_max_open = get_unaligned_be32(&buf[16]); + return 0; } + /* Host-managed */ + sdkp->urswrz = buf[4] & 1; + sdkp->zones_optimal_open = 0; + sdkp->zones_optimal_nonseq = 0; + sdkp->zones_max_open = get_unaligned_be32(&buf[16]); + /* * Check for unconstrained reads: host-managed devices with * constrained reads (drives failing read after write pointer) From patchwork Thu Apr 21 18:30:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 564714 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA396C433EF for ; Thu, 21 Apr 2022 18:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391389AbiDUSdo (ORCPT ); Thu, 21 Apr 2022 14:33:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54008 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391179AbiDUSdg (ORCPT ); Thu, 21 Apr 2022 14:33:36 -0400 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2FB834BB86 for ; Thu, 21 Apr 2022 11:30:46 -0700 (PDT) Received: by mail-pl1-f178.google.com with SMTP id n18so5648528plg.5 for ; Thu, 21 Apr 2022 11:30:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SuCs1vqJY4UaDr670U24z1wPqlN25fEf3ZxbjscCIFE=; b=temNWAZQV170t9SujU8Etrf0J234dNB0YB3W848a1UarAoZhnynnrTUfGjGTwG6Fnu g4A1hNJJRcVs40JhCWUulyW1TaW4oztcoMQmP8E+fq/TtDicWLCM4jliCToWtFGEY5gl 1tqLVHU1eTjx7+JYgDk5nm9ljEuEB0+73uiNd8G4rwSGwJ7UWknON3tCvPRosqPgHXS2 I4pbJt98lFMhAXIP+m5Ud/TlECHdcXcEGOuO11/5EdZnMVPdcek8TRfC86rGJjl2AaW3 0J1LLFZ+b6roHlRqSc1YEhoSrkpsf5ACqtEQ4RyVQwYMiQckDQERpMmarxTOE1h/dAWR Vdog== X-Gm-Message-State: AOAM531FUjih4YZGKVUPr75cOSVfG9NTTI0QqKrcif5LHp384gC4IkmZ EvRbOqWMMpA7WkhBT1IbiMw= X-Google-Smtp-Source: ABdhPJy8I0x8AkWU/oLPkpXx5JxcSYG0zW+nWOFisVwjGuJtKsHBtk51ngh4QwXR/8qz2TeabueOVQ== X-Received: by 2002:a17:90b:4f82:b0:1d1:b8fd:7e36 with SMTP id qe2-20020a17090b4f8200b001d1b8fd7e36mr11881796pjb.194.1650565845533; Thu, 21 Apr 2022 11:30:45 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:44 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 6/9] scsi: sd_zbc: Hide gap zones Date: Thu, 21 Apr 2022 11:30:20 -0700 Message-Id: <20220421183023.3462291-7-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org ZBC-2 allows host-managed disks to report gap zones. This allow zoned disks to report an offset between data zone starts that is a power of two even if the number of logical blocks with data per zone is not a power of two. Another new feature in ZBC-2 is support for constant zone starting LBA offsets. For zoned disks that report a constant zone starting LBA offset, hide the gap zones from the block layer. Report the offset between data zone starts as zone size and report the number of logical blocks with data per zone as the zone capacity. Signed-off-by: Damien Le Moal [ bvanassche: Reworked this patch ] Signed-off-by: Bart Van Assche --- drivers/scsi/sd.h | 5 ++ drivers/scsi/sd_zbc.c | 105 +++++++++++++++++++++++++++++++++----- include/scsi/scsi_proto.h | 9 +++- 3 files changed, 105 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 47434f905b0a..d249933ba69e 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -99,6 +99,11 @@ struct scsi_disk { u32 zones_optimal_open; u32 zones_optimal_nonseq; u32 zones_max_open; + /* + * Either zero or a power of two. If not zero it means that the offset + * between zone starting LBAs is constant. + */ + u32 zone_starting_lba_gran; u32 *zones_wp_offset; spinlock_t zones_wp_offset_lock; u32 *rev_wp_offset; diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index c53e166362b9..5b9fad70aa88 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -50,6 +50,12 @@ static unsigned int sd_zbc_get_zone_wp_offset(struct blk_zone *zone) } } +/* Whether or not a SCSI zone descriptor describes a gap zone. */ +static bool sd_zbc_is_gap_zone(const u8 buf[64]) +{ + return (buf[0] & 0xf) == ZBC_ZONE_TYPE_GAP; +} + /** * sd_zbc_parse_report - Parse a SCSI zone descriptor * @sdkp: SCSI disk pointer. @@ -69,8 +75,12 @@ static int sd_zbc_parse_report(struct scsi_disk *sdkp, const u8 buf[64], { struct scsi_device *sdp = sdkp->device; struct blk_zone zone = { 0 }; + sector_t start_lba, gran; int ret; + if (WARN_ON_ONCE(sd_zbc_is_gap_zone(buf))) + return -EINVAL; + zone.type = buf[0] & 0x0f; zone.cond = (buf[1] >> 4) & 0xf; if (buf[1] & 0x01) @@ -78,9 +88,27 @@ static int sd_zbc_parse_report(struct scsi_disk *sdkp, const u8 buf[64], if (buf[1] & 0x02) zone.non_seq = 1; - zone.len = logical_to_sectors(sdp, get_unaligned_be64(&buf[8])); - zone.capacity = zone.len; - zone.start = logical_to_sectors(sdp, get_unaligned_be64(&buf[16])); + start_lba = get_unaligned_be64(&buf[16]); + zone.start = logical_to_sectors(sdp, start_lba); + zone.capacity = logical_to_sectors(sdp, get_unaligned_be64(&buf[8])); + zone.len = zone.capacity; + if (sdkp->zone_starting_lba_gran) { + gran = logical_to_sectors(sdp, sdkp->zone_starting_lba_gran); + if (zone.len > gran) { + sd_printk(KERN_ERR, sdkp, + "Invalid zone at LBA %llu with capacity %llu and length %llu; granularity = %llu\n", + start_lba, + sectors_to_logical(sdp, zone.capacity), + sectors_to_logical(sdp, zone.len), + sectors_to_logical(sdp, gran)); + return -EINVAL; + } + /* + * Use the starting LBA granularity instead of the zone length + * obtained from the REPORT ZONES command. + */ + zone.len = gran; + } if (zone.cond == ZBC_ZONE_COND_FULL) zone.wp = zone.start + zone.len; else @@ -227,6 +255,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, sector_t lba = sectors_to_logical(sdkp->device, sector); unsigned int nr, i; unsigned char *buf; + u64 zone_length, start_lba; size_t offset, buflen = 0; int zone_idx = 0; int ret; @@ -255,14 +284,36 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, for (i = 0; i < nr && zone_idx < nr_zones; i++) { offset += 64; + start_lba = get_unaligned_be64(&buf[offset + 16]); + zone_length = get_unaligned_be64(&buf[offset + 8]); + if ((zone_idx == 0 && + (lba < start_lba || + lba >= start_lba + zone_length)) || + (zone_idx > 0 && start_lba != lba) || + start_lba + zone_length < start_lba) { + sd_printk(KERN_ERR, sdkp, + "Zone %d at LBA %llu is invalid: %llu + %llu\n", + zone_idx, lba, start_lba, zone_length); + ret = -EINVAL; + goto out; + } + lba = start_lba + zone_length; + if (sd_zbc_is_gap_zone(&buf[offset])) { + if (sdkp->zone_starting_lba_gran) + continue; + sd_printk(KERN_ERR, sdkp, + "Gap zone without constant LBA offsets\n"); + ret = -EINVAL; + goto out; + } + ret = sd_zbc_parse_report(sdkp, buf + offset, zone_idx, cb, data); if (ret) goto out; + zone_idx++; } - - lba += sdkp->zone_info.zone_blocks * i; } ret = zone_idx; @@ -579,6 +630,7 @@ unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes, static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, unsigned char *buf) { + u64 zone_starting_lba_gran; if (scsi_get_vpd_page(sdkp->device, 0xb6, buf, 64)) { sd_printk(KERN_NOTICE, sdkp, @@ -600,6 +652,29 @@ static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, sdkp->zones_optimal_open = 0; sdkp->zones_optimal_nonseq = 0; sdkp->zones_max_open = get_unaligned_be32(&buf[16]); + /* Check zone alignment method */ + switch (buf[23] & 0xf) { + case 0: + case ZBC_CONSTANT_ZONE_LENGTH: + /* Use zone length */ + break; + case ZBC_CONSTANT_ZONE_START_OFFSET: + zone_starting_lba_gran = get_unaligned_be64(&buf[24]); + if (zone_starting_lba_gran == 0 || + !is_power_of_2(zone_starting_lba_gran) || + logical_to_sectors(sdkp->device, zone_starting_lba_gran) > + UINT_MAX) { + sd_printk(KERN_ERR, sdkp, + "Invalid zone starting LBA granularity %llu\n", + zone_starting_lba_gran); + return -ENODEV; + } + sdkp->zone_starting_lba_gran = zone_starting_lba_gran; + break; + default: + sd_printk(KERN_ERR, sdkp, "Invalid zone alignment method\n"); + return -ENODEV; + } /* * Check for unconstrained reads: host-managed devices with @@ -654,14 +729,18 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf, } } - /* Get the size of the first reported zone */ - rec = buf + 64; - zone_blocks = get_unaligned_be64(&rec[8]); - if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { - if (sdkp->first_scan) - sd_printk(KERN_NOTICE, sdkp, - "Zone size too large\n"); - return -EFBIG; + if (sdkp->zone_starting_lba_gran == 0) { + /* Get the size of the first reported zone */ + rec = buf + 64; + zone_blocks = get_unaligned_be64(&rec[8]); + if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { + if (sdkp->first_scan) + sd_printk(KERN_NOTICE, sdkp, + "Zone size too large\n"); + return -EFBIG; + } + } else { + zone_blocks = sdkp->zone_starting_lba_gran; } if (!is_power_of_2(zone_blocks)) { diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h index f017843a8124..c03e35fc382c 100644 --- a/include/scsi/scsi_proto.h +++ b/include/scsi/scsi_proto.h @@ -307,7 +307,9 @@ enum zbc_zone_type { ZBC_ZONE_TYPE_CONV = 0x1, ZBC_ZONE_TYPE_SEQWRITE_REQ = 0x2, ZBC_ZONE_TYPE_SEQWRITE_PREF = 0x3, - /* 0x4 to 0xf are reserved */ + ZBC_ZONE_TYPE_SEQ_OR_BEFORE_REQ = 0x4, + ZBC_ZONE_TYPE_GAP = 0x5, + /* 0x6 to 0xf are reserved */ }; /* Zone conditions of REPORT ZONES zone descriptors */ @@ -323,6 +325,11 @@ enum zbc_zone_cond { ZBC_ZONE_COND_OFFLINE = 0xf, }; +enum zbc_zone_alignment_method { + ZBC_CONSTANT_ZONE_LENGTH = 0x1, + ZBC_CONSTANT_ZONE_START_OFFSET = 0x8, +}; + /* Version descriptor values for INQUIRY */ enum scsi_version_descriptor { SCSI_VERSION_DESCRIPTOR_FCP4 = 0x0a40, From patchwork Thu Apr 21 18:30:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 565588 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCB4AC433F5 for ; Thu, 21 Apr 2022 18:30:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391390AbiDUSdq (ORCPT ); Thu, 21 Apr 2022 14:33:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391373AbiDUSdi (ORCPT ); Thu, 21 Apr 2022 14:33:38 -0400 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C67604BB88 for ; Thu, 21 Apr 2022 11:30:47 -0700 (PDT) Received: by mail-pg1-f180.google.com with SMTP id bg9so5333095pgb.9 for ; Thu, 21 Apr 2022 11:30:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hS+x0W+keuoHTFQsjWjH8UYkZViOvD+uCeBfkMeHRfI=; b=d49Pa58BBxr8wt+F670KLDQ3NWzobVhsDAaTZA8Wue2wyz1Nk6dl4Pwa2jegD9UJvM MHrsdEJTp5jKanpoTMDgb/m+3KeWcFJXWLgxamIGwM98YkeJM1yvl4A++dKBJRh9Sux8 nTi4hJgSO1DH9rhjRHx62ZvcqJe5h0qh2pZplNgqgySFokZjuFqjgrZLiXpUD9sgWjpK nw4KQ9j0iSc1u4hsDg6cCjDFtrk9GhLVRXkgfuhQZk9E/oGyJl4KBAqH385PA6OHcN3U HnODhK+fnnyATfJcXvO70pOU2UsOFbpg63L6YfmwilXrilVko9jCHzrisRalisUmoZpN 08zQ== X-Gm-Message-State: AOAM533+hvudK+E/xiXpktNL+pEP9eOK88ucJ07FrDmkTvdbEIzSyl4Z D+8xeVD7CduRFqKoRwI63R0= X-Google-Smtp-Source: ABdhPJwVg+at6eKDGwueJ/ycGHslHfItCzPdXLap5PsKfeHekd7CLnd2CeYnN/LKKkdrDeIvJDFJUw== X-Received: by 2002:a65:6956:0:b0:399:1f0e:6172 with SMTP id w22-20020a656956000000b003991f0e6172mr645044pgq.286.1650565847239; Thu, 21 Apr 2022 11:30:47 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:46 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 7/9] scsi_debug: Fix a typo Date: Thu, 21 Apr 2022 11:30:21 -0700 Message-Id: <20220421183023.3462291-8-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Change a single occurrence of "nad" into "and". Cc: Douglas Gilbert Reviewed-by: Damien Le Moal Signed-off-by: Bart Van Assche --- drivers/scsi/scsi_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index c607755cce00..7cfae8206a4b 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -4408,7 +4408,7 @@ static int resp_verify(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) #define RZONES_DESC_HD 64 -/* Report zones depending on start LBA nad reporting options */ +/* Report zones depending on start LBA and reporting options */ static int resp_report_zones(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { From patchwork Thu Apr 21 18:30:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 564713 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A5EFC433F5 for ; Thu, 21 Apr 2022 18:31:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391396AbiDUSdt (ORCPT ); Thu, 21 Apr 2022 14:33:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391369AbiDUSdk (ORCPT ); Thu, 21 Apr 2022 14:33:40 -0400 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4D6D4BB80 for ; Thu, 21 Apr 2022 11:30:49 -0700 (PDT) Received: by mail-pf1-f182.google.com with SMTP id i24so5759925pfa.7 for ; Thu, 21 Apr 2022 11:30:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pX8d48ZPCsQGTJ4Rx6/9uqNJV4YJFux4MxoOiukWboc=; b=AjOxDJx+InmMlpxiGEyUM+k64T/gYFyYp4e5sPhujajv2zeXKXmTbdxNJ0HSzdjh92 FTfa03ZuoNUv98PCXVJaeAvHHhq35yWzkqiD9THGyk8V3qMrlu0Bg1LPf9idm0IGCULL WGnxYcpEdYz253aHLPmdO7gdlrVLdv29k42IDABqkh5goephs6ROULpdGjvLrXu+ZiBO rAYqp8klmjNhjdUJ/0s8e+snfhH892/AuQXBLamdVKVgkpmGy0H6STRh850Mw3C1U2Ki Q6VjTSLjwtU14TJfn+2Maw1rmAMaTFs2puBhILk04Q5vfvpI/lkvzogOJeD4QO8rlbVW LDwg== X-Gm-Message-State: AOAM531UUBhqVabjvjdws8zijiIzSMIGSoWtcVZIiQWolcs9jA1gI+CU W3quMsL2B4G0YV8UEmRneUE= X-Google-Smtp-Source: ABdhPJwxpTUR1WYu7hoQ6e3MuuV9PrUWbge47/XIWyOx1jBJyl7+la4UDeVfipBQ1BJfq6QiD+hgcw== X-Received: by 2002:a63:cc53:0:b0:372:7d69:49fb with SMTP id q19-20020a63cc53000000b003727d6949fbmr633963pgi.21.1650565849153; Thu, 21 Apr 2022 11:30:49 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:48 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 8/9] scsi_debug: Rename zone type constants Date: Thu, 21 Apr 2022 11:30:22 -0700 Message-Id: <20220421183023.3462291-9-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Rename the scsi_debug zone type constants to prevent a conflict with the ZBC_ZONE_TYPE_GAP constant from include/scsi/scsi_proto.h. Cc: Douglas Gilbert Signed-off-by: Damien Le Moal [ bvanassche: Extracted these changes from a larger patch ] Signed-off-by: Bart Van Assche --- drivers/scsi/scsi_debug.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 7cfae8206a4b..47cec83a4b7c 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -252,9 +252,9 @@ static const char *sdebug_version_date = "20210520"; /* Zone types (zbcr05 table 25) */ enum sdebug_z_type { - ZBC_ZONE_TYPE_CNV = 0x1, - ZBC_ZONE_TYPE_SWR = 0x2, - ZBC_ZONE_TYPE_SWP = 0x3, + ZBC_ZTYPE_CNV = 0x1, + ZBC_ZTYPE_SWR = 0x2, + ZBC_ZTYPE_SWP = 0x3, }; /* enumeration names taken from table 26, zbcr05 */ @@ -2720,7 +2720,7 @@ static struct sdeb_zone_state *zbc_zone(struct sdebug_dev_info *devip, static inline bool zbc_zone_is_conv(struct sdeb_zone_state *zsp) { - return zsp->z_type == ZBC_ZONE_TYPE_CNV; + return zsp->z_type == ZBC_ZTYPE_CNV; } static void zbc_close_zone(struct sdebug_dev_info *devip, @@ -2801,7 +2801,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip, if (zbc_zone_is_conv(zsp)) return; - if (zsp->z_type == ZBC_ZONE_TYPE_SWR) { + if (zsp->z_type == ZBC_ZTYPE_SWR) { zsp->z_wp += num; if (zsp->z_wp >= zend) zsp->z_cond = ZC5_FULL; @@ -2868,7 +2868,7 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, return 0; } - if (zsp->z_type == ZBC_ZONE_TYPE_SWR) { + if (zsp->z_type == ZBC_ZTYPE_SWR) { /* Writes cannot cross sequential zone boundaries */ if (zsp_end != zsp) { mk_sense_buffer(scp, ILLEGAL_REQUEST, @@ -5005,14 +5005,14 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip) zsp->z_start = zstart; if (i < devip->nr_conv_zones) { - zsp->z_type = ZBC_ZONE_TYPE_CNV; + zsp->z_type = ZBC_ZTYPE_CNV; zsp->z_cond = ZBC_NOT_WRITE_POINTER; zsp->z_wp = (sector_t)-1; } else { if (devip->zmodel == BLK_ZONED_HM) - zsp->z_type = ZBC_ZONE_TYPE_SWR; + zsp->z_type = ZBC_ZTYPE_SWR; else - zsp->z_type = ZBC_ZONE_TYPE_SWP; + zsp->z_type = ZBC_ZTYPE_SWP; zsp->z_cond = ZC1_EMPTY; zsp->z_wp = zsp->z_start; } From patchwork Thu Apr 21 18:30:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 565587 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0078CC433EF for ; Thu, 21 Apr 2022 18:31:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1391385AbiDUSdu (ORCPT ); Thu, 21 Apr 2022 14:33:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1391368AbiDUSdn (ORCPT ); Thu, 21 Apr 2022 14:33:43 -0400 Received: from mail-pg1-f177.google.com (mail-pg1-f177.google.com [209.85.215.177]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91C184BB85 for ; Thu, 21 Apr 2022 11:30:51 -0700 (PDT) Received: by mail-pg1-f177.google.com with SMTP id t4so5358648pgc.1 for ; Thu, 21 Apr 2022 11:30:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1NEVzUEH6vJmuRIkixQzXIWGPc9+5aPpkZDRTi35S/Q=; b=V5PtR438wPFM8t4xkhe619Mew2CBnsIt3oEq+J0PmAZR6PbCYIs0ab/pPgTsfSZcNr nZYZIEcInHrtUBdTAfOn0SpzkzMg4N4yg5ip8Yq+qEzbJp63iXtO5fI/VtkTFKMnrvac 2J0YwvMUviEsdHZDrRFRptrGVKyPEAxQ/fFjQPGfCaM/fp3TgPt4pGeSiedpcnSunrsE GkHx/En3DEuDvvI7PcsgJ629tpJe9v3RqitUqVUEJhUvt0TlTC7TNLZ1elR+Lp9PSGyK JQSwR233x7VJCV/Eg+G2i5h+rvm8tqd5h2PnSpi1xQKLfKXYjLm01XMzJq5JdbQClqfy jzOQ== X-Gm-Message-State: AOAM531XbbhUfjsi7LuQA6s15xioit9G6q0iXwpKWzBEJWJVOEdsU9fV lH4Sj+Vlcabrjvb+/4pHsJU= X-Google-Smtp-Source: ABdhPJxo5H1Kph/BqPvZi2EfIyhizxHc0IXhInh54X6EvgE9Ta5GRWJThmf3lRy7PHAbOk8UyeDygw== X-Received: by 2002:a65:410a:0:b0:399:38b9:8ba with SMTP id w10-20020a65410a000000b0039938b908bamr632128pgp.526.1650565850980; Thu, 21 Apr 2022 11:30:50 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:a034:31d8:ca4e:1f35]) by smtp.gmail.com with ESMTPSA id a22-20020a62d416000000b0050bd98eaccbsm2181079pfh.213.2022.04.21.11.30.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 11:30:50 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , Damien Le Moal , Hannes Reinecke , Shaun Tancheff , Douglas Gilbert , linux-scsi@vger.kernel.org, Bart Van Assche , "James E.J. Bottomley" Subject: [PATCH v2 9/9] scsi_debug: Add gap zone support Date: Thu, 21 Apr 2022 11:30:23 -0700 Message-Id: <20220421183023.3462291-10-bvanassche@acm.org> X-Mailer: git-send-email 2.36.0.rc2.479.g8af0fa9b8e-goog In-Reply-To: <20220421183023.3462291-1-bvanassche@acm.org> References: <20220421183023.3462291-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Add the 'zone_cap_mb' kernel module parameter. This parameter defines the zone capacity. The zone capacity must be less than or equal to the zone size. Report that sequential write zones and gap zones are paired in the Zoned Block Device Characteristics VPD page (page B6h). This patch has been tested as follows: modprobe scsi_debug delay=0 sector_size=512 dev_size_mb=128 zbc=host-managed zone_nr_conv=16 zone_size_mb=4 zone_cap_mb=3 modprobe brd rd_nr=1 rd_size=$((1<<20)) mkfs.f2fs -m /dev/ram0 -c /dev/${scsi_debug_dev} mount /dev/ram0 /mnt # Run a fio job that uses /mnt Cc: Douglas Gilbert Signed-off-by: Damien Le Moal [ bvanassche: Switched to reporting a constant zone starting LBA granularity ] Signed-off-by: Bart Van Assche --- drivers/scsi/scsi_debug.c | 129 ++++++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 47cec83a4b7c..d4ab21c5d26a 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -16,7 +16,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ #include - +#include #include #include #include @@ -99,6 +99,7 @@ static const char *sdebug_version_date = "20210520"; #define WRITE_BOUNDARY_ASCQ 0x5 #define READ_INVDATA_ASCQ 0x6 #define READ_BOUNDARY_ASCQ 0x7 +#define ATTEMPT_ACCESS_GAP 0x9 #define INSUFF_ZONE_ASCQ 0xe /* Additional Sense Code Qualifier (ASCQ) */ @@ -255,6 +256,8 @@ enum sdebug_z_type { ZBC_ZTYPE_CNV = 0x1, ZBC_ZTYPE_SWR = 0x2, ZBC_ZTYPE_SWP = 0x3, + /* ZBC_ZTYPE_SOBR = 0x4, */ + ZBC_ZTYPE_GAP = 0x5, }; /* enumeration names taken from table 26, zbcr05 */ @@ -292,10 +295,12 @@ struct sdebug_dev_info { /* For ZBC devices */ enum blk_zoned_model zmodel; + unsigned int zcap; unsigned int zsize; unsigned int zsize_shift; unsigned int nr_zones; unsigned int nr_conv_zones; + unsigned int nr_seq_zones; unsigned int nr_imp_open; unsigned int nr_exp_open; unsigned int nr_closed; @@ -833,6 +838,7 @@ static int dif_errors; /* ZBC global data */ static bool sdeb_zbc_in_use; /* true for host-aware and host-managed disks */ +static int sdeb_zbc_zone_cap_mb; static int sdeb_zbc_zone_size_mb; static int sdeb_zbc_max_open = DEF_ZBC_MAX_OPEN_ZONES; static int sdeb_zbc_nr_conv = DEF_ZBC_NR_CONV_ZONES; @@ -1563,6 +1569,12 @@ static int inquiry_vpd_b6(struct sdebug_dev_info *devip, unsigned char *arr) put_unaligned_be32(devip->max_open, &arr[12]); else put_unaligned_be32(0xffffffff, &arr[12]); + if (devip->zcap < devip->zsize) { + arr[19] = ZBC_CONSTANT_ZONE_START_OFFSET; + put_unaligned_be64(devip->zsize, &arr[20]); + } else { + arr[19] = 0; + } return 0x3c; } @@ -2715,7 +2727,23 @@ static inline bool sdebug_dev_is_zoned(struct sdebug_dev_info *devip) static struct sdeb_zone_state *zbc_zone(struct sdebug_dev_info *devip, unsigned long long lba) { - return &devip->zstate[lba >> devip->zsize_shift]; + u32 zno = lba >> devip->zsize_shift; + struct sdeb_zone_state *zsp; + + if (devip->zcap == devip->zsize || zno < devip->nr_conv_zones) + return &devip->zstate[zno]; + + /* + * If the zone capacity is less than the zone size, adjust for gap + * zones. + */ + zno = 2 * zno - devip->nr_conv_zones; + WARN_ONCE(zno >= devip->nr_zones, "%u > %u\n", zno, devip->nr_zones); + zsp = &devip->zstate[zno]; + if (lba >= zsp->z_start + zsp->z_size) + zsp++; + WARN_ON_ONCE(lba >= zsp->z_start + zsp->z_size); + return zsp; } static inline bool zbc_zone_is_conv(struct sdeb_zone_state *zsp) @@ -2723,12 +2751,22 @@ static inline bool zbc_zone_is_conv(struct sdeb_zone_state *zsp) return zsp->z_type == ZBC_ZTYPE_CNV; } +static inline bool zbc_zone_is_gap(struct sdeb_zone_state *zsp) +{ + return zsp->z_type == ZBC_ZTYPE_GAP; +} + +static inline bool zbc_zone_is_seq(struct sdeb_zone_state *zsp) +{ + return !zbc_zone_is_conv(zsp) && !zbc_zone_is_gap(zsp); +} + static void zbc_close_zone(struct sdebug_dev_info *devip, struct sdeb_zone_state *zsp) { enum sdebug_z_cond zc; - if (zbc_zone_is_conv(zsp)) + if (!zbc_zone_is_seq(zsp)) return; zc = zsp->z_cond; @@ -2766,7 +2804,7 @@ static void zbc_open_zone(struct sdebug_dev_info *devip, { enum sdebug_z_cond zc; - if (zbc_zone_is_conv(zsp)) + if (!zbc_zone_is_seq(zsp)) return; zc = zsp->z_cond; @@ -2798,7 +2836,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip, struct sdeb_zone_state *zsp = zbc_zone(devip, lba); unsigned long long n, end, zend = zsp->z_start + zsp->z_size; - if (zbc_zone_is_conv(zsp)) + if (!zbc_zone_is_seq(zsp)) return; if (zsp->z_type == ZBC_ZTYPE_SWR) { @@ -2846,9 +2884,7 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, if (devip->zmodel == BLK_ZONED_HA) return 0; /* For host-managed, reads cannot cross zone types boundaries */ - if (zsp_end != zsp && - zbc_zone_is_conv(zsp) && - !zbc_zone_is_conv(zsp_end)) { + if (zsp->z_type != zsp_end->z_type) { mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, READ_INVDATA_ASCQ); @@ -2857,6 +2893,13 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, return 0; } + /* Writing into a gap zone is not allowed */ + if (zbc_zone_is_gap(zsp)) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, + ATTEMPT_ACCESS_GAP); + return check_condition_result; + } + /* No restrictions for writes within conventional zones */ if (zbc_zone_is_conv(zsp)) { if (!zbc_zone_is_conv(zsp_end)) { @@ -4412,14 +4455,14 @@ static int resp_verify(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) static int resp_report_zones(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { - unsigned int i, max_zones, rep_max_zones, nrz = 0; + unsigned int rep_max_zones, nrz = 0; int ret = 0; u32 alloc_len, rep_opts, rep_len; bool partial; u64 lba, zs_lba; u8 *arr = NULL, *desc; u8 *cmd = scp->cmnd; - struct sdeb_zone_state *zsp; + struct sdeb_zone_state *zsp = NULL; struct sdeb_store_info *sip = devip2sip(devip, false); if (!sdebug_dev_is_zoned(devip)) { @@ -4438,9 +4481,7 @@ static int resp_report_zones(struct scsi_cmnd *scp, return check_condition_result; } - max_zones = devip->nr_zones - (zs_lba >> devip->zsize_shift); - rep_max_zones = min((alloc_len - 64) >> ilog2(RZONES_DESC_HD), - max_zones); + rep_max_zones = (alloc_len - 64) >> ilog2(RZONES_DESC_HD); arr = kzalloc(alloc_len, GFP_ATOMIC); if (!arr) { @@ -4452,9 +4493,9 @@ static int resp_report_zones(struct scsi_cmnd *scp, sdeb_read_lock(sip); desc = arr + 64; - for (i = 0; i < max_zones; i++) { - lba = zs_lba + devip->zsize * i; - if (lba > sdebug_capacity) + for (lba = zs_lba; lba < sdebug_capacity; + lba = zsp->z_start + zsp->z_size) { + if (WARN_ONCE(zbc_zone(devip, lba) == zsp, "lba = %llu\n", lba)) break; zsp = zbc_zone(devip, lba); switch (rep_opts) { @@ -4499,9 +4540,14 @@ static int resp_report_zones(struct scsi_cmnd *scp, if (!zsp->z_non_seq_resource) continue; break; + case 0x3e: + /* All zones except gap zones. */ + if (zbc_zone_is_gap(zsp)) + continue; + break; case 0x3f: /* Not write pointer (conventional) zones */ - if (!zbc_zone_is_conv(zsp)) + if (zbc_zone_is_seq(zsp)) continue; break; default: @@ -4530,8 +4576,13 @@ static int resp_report_zones(struct scsi_cmnd *scp, } /* Report header */ + /* Zone list length. */ put_unaligned_be32(nrz * RZONES_DESC_HD, arr + 0); + /* Maximum LBA */ put_unaligned_be64(sdebug_capacity - 1, arr + 8); + /* Zone starting LBA granularity. */ + if (devip->zcap < devip->zsize) + put_unaligned_be64(devip->zsize, arr + 16); rep_len = (unsigned long)desc - (unsigned long)arr; ret = fill_from_dev_buffer(scp, arr, min_t(u32, alloc_len, rep_len)); @@ -4756,7 +4807,7 @@ static void zbc_rwp_zone(struct sdebug_dev_info *devip, enum sdebug_z_cond zc; struct sdeb_store_info *sip = devip2sip(devip, false); - if (zbc_zone_is_conv(zsp)) + if (!zbc_zone_is_seq(zsp)) return; zc = zsp->z_cond; @@ -4946,6 +4997,7 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip) { struct sdeb_zone_state *zsp; sector_t capacity = get_sdebug_capacity(); + sector_t conv_capacity; sector_t zstart = 0; unsigned int i; @@ -4980,11 +5032,30 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip) devip->zsize_shift = ilog2(devip->zsize); devip->nr_zones = (capacity + devip->zsize - 1) >> devip->zsize_shift; - if (sdeb_zbc_nr_conv >= devip->nr_zones) { + if (sdeb_zbc_zone_cap_mb == 0) { + devip->zcap = devip->zsize; + } else { + devip->zcap = (sdeb_zbc_zone_cap_mb * SZ_1M) >> + ilog2(sdebug_sector_size); + if (devip->zcap > devip->zsize) { + pr_err("Zone capacity too large\n"); + return -EINVAL; + } + } + + conv_capacity = (sector_t)sdeb_zbc_nr_conv << devip->zsize_shift; + if (conv_capacity >= capacity) { pr_err("Number of conventional zones too large\n"); return -EINVAL; } devip->nr_conv_zones = sdeb_zbc_nr_conv; + devip->nr_seq_zones = ALIGN(capacity - conv_capacity, devip->zsize) >> + devip->zsize_shift; + devip->nr_zones = devip->nr_conv_zones + devip->nr_seq_zones; + + /* Add gap zones if zone capacity is smaller than the zone size */ + if (devip->zcap < devip->zsize) + devip->nr_zones += devip->nr_seq_zones; if (devip->zmodel == BLK_ZONED_HM) { /* zbc_max_open_zones can be 0, meaning "not reported" */ @@ -5008,20 +5079,26 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip) zsp->z_type = ZBC_ZTYPE_CNV; zsp->z_cond = ZBC_NOT_WRITE_POINTER; zsp->z_wp = (sector_t)-1; - } else { + zsp->z_size = + min_t(u64, devip->zsize, capacity - zstart); + } else if ((zstart & (devip->zsize - 1)) == 0) { if (devip->zmodel == BLK_ZONED_HM) zsp->z_type = ZBC_ZTYPE_SWR; else zsp->z_type = ZBC_ZTYPE_SWP; zsp->z_cond = ZC1_EMPTY; zsp->z_wp = zsp->z_start; + zsp->z_size = + min_t(u64, devip->zcap, capacity - zstart); + } else { + zsp->z_type = ZBC_ZTYPE_GAP; + zsp->z_cond = ZBC_NOT_WRITE_POINTER; + zsp->z_wp = (sector_t)-1; + zsp->z_size = min_t(u64, devip->zsize - devip->zcap, + capacity - zstart); } - if (zsp->z_start + devip->zsize < capacity) - zsp->z_size = devip->zsize; - else - zsp->z_size = capacity - zsp->z_start; - + WARN_ON_ONCE((int)zsp->z_size <= 0); zstart += zsp->z_size; } @@ -5856,6 +5933,7 @@ module_param_named(wp, sdebug_wp, bool, S_IRUGO | S_IWUSR); module_param_named(write_same_length, sdebug_write_same_length, int, S_IRUGO | S_IWUSR); module_param_named(zbc, sdeb_zbc_model_s, charp, S_IRUGO); +module_param_named(zone_cap_mb, sdeb_zbc_zone_cap_mb, int, S_IRUGO); module_param_named(zone_max_open, sdeb_zbc_max_open, int, S_IRUGO); module_param_named(zone_nr_conv, sdeb_zbc_nr_conv, int, S_IRUGO); module_param_named(zone_size_mb, sdeb_zbc_zone_size_mb, int, S_IRUGO); @@ -5927,6 +6005,7 @@ MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique de MODULE_PARM_DESC(wp, "Write Protect (def=0)"); MODULE_PARM_DESC(write_same_length, "Maximum blocks per WRITE SAME cmd (def=0xffff)"); MODULE_PARM_DESC(zbc, "'none' [0]; 'aware' [1]; 'managed' [2] (def=0). Can have 'host-' prefix"); +MODULE_PARM_DESC(zone_cap_mb, "Zone capacity in MiB (def=zone size)"); MODULE_PARM_DESC(zone_max_open, "Maximum number of open zones; [0] for no limit (def=auto)"); MODULE_PARM_DESC(zone_nr_conv, "Number of conventional zones (def=1)"); MODULE_PARM_DESC(zone_size_mb, "Zone size in MiB (def=auto)");