From patchwork Sat Sep 10 05:27:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12972383 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 68B99C6FA82 for ; Sat, 10 Sep 2022 05:31:44 +0000 (UTC) Received: from localhost ([::1]:35910 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWt5j-00058q-Ex for qemu-devel@archiver.kernel.org; Sat, 10 Sep 2022 01:31:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60118) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWt2m-0002A5-Up; Sat, 10 Sep 2022 01:28:42 -0400 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]:44905) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oWt2k-0004n9-4H; Sat, 10 Sep 2022 01:28:39 -0400 Received: by mail-pl1-x634.google.com with SMTP id 9so3604505plj.11; Fri, 09 Sep 2022 22:28:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=u7Vyf1KXlekn86IvpZl1aTdlqQKIB8UmDy2XqOY+20U=; b=VKJfU61AGSiMm4RcCj4Z6wjfhDu1Qq91CZjhI65BI1hX11vIJWozqF9QxSkMi1tMwI mvgvIruw5hT6UhlJ0oMLjoBdTKZKNcSz7gmd0sihHMIfHIHD2Muxbzp7c4BvjmDN1Nf8 ctToLQfuOlENLoocWfN7mK9Ep9oDsEZeSmjc5Q0PU14zeUDM5JQeplznn3INzGK5Gm5m kaU6xjy9+rnK+BvNgqd3X26LFt8tJRs+PBSgvcSDqfnaUrQ9DvCjpm2VoR3Na60mqnkC 0aCBkawOv+ClR+CoQJcpCNGWgpq814P8btWcsviALFAS2WvfHR4fII36qSoJdywLSk1v QUIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=u7Vyf1KXlekn86IvpZl1aTdlqQKIB8UmDy2XqOY+20U=; b=SiqhX3n+PqHJknP8j41B0CvezZoASAIlMrqqNUXyBGGJFzR31gpMbpBA6KLDJyAF7F kUwfmwUrXOdbFMoCovEk+twISGdXeo6GA0bvbSAyT6lVYRxf1SkVNeMk1xLdp7bXLvIY 5tz7Wc4Fz9E+cBS8TFZndA+Rgmos53sfNX5AO0uNc7MptMGWdrBivz5eKb5TOrq/LYwS Tb6WNJC+n1kejkfVDNUK5pvfjFAEMOFT1BNTRN92ePPsgYl4gFH+L8BwSPN0o2QfIXn8 H2N+WTrCU4uCTkgBmPumcp+jUqoTV4RvhUOekNsV7+FiaW+3xIscdPC48RTiCiE3U88s mopg== X-Gm-Message-State: ACgBeo2c+qn4ss1KKRvgAortxx1RrOxP13SvFS61XaO/0EbBCAhVzOkt WvCzNr8Y8Vf5ssu+WL6OMsnwr2xZN5nkKvre X-Google-Smtp-Source: AA6agR4TzcAIdX8nIYSRFraYJ+S0iDeEuhk6PRXDtMfdK23jex7/P3/vLjYodkRsdquKWoRNL7qsRw== X-Received: by 2002:a17:902:6bca:b0:173:cfae:a7e5 with SMTP id m10-20020a1709026bca00b00173cfaea7e5mr16666051plt.39.1662787716176; Fri, 09 Sep 2022 22:28:36 -0700 (PDT) Received: from roots.. ([183.221.93.83]) by smtp.gmail.com with ESMTPSA id y6-20020aa793c6000000b00540d75197e5sm731994pff.47.2022.09.09.22.28.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Sep 2022 22:28:35 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: dmitry.fomichev@wdc.com, Markus Armbruster , Eric Blake , qemu-block@nongnu.org, Stefan Hajnoczi , Kevin Wolf , Fam Zheng , damien.lemoal@opensource.wdc.com, hare@suse.de, Hanna Reitz , Sam Li Subject: [PATCH v9 1/7] include: add zoned device structs Date: Sat, 10 Sep 2022 13:27:53 +0800 Message-Id: <20220910052759.27517-2-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220910052759.27517-1-faithilikerun@gmail.com> References: <20220910052759.27517-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::634; envelope-from=faithilikerun@gmail.com; helo=mail-pl1-x634.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi Reviewed-by: Damien Le Moal --- include/block/block-common.h | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/include/block/block-common.h b/include/block/block-common.h index fdb7306e78..36bd0e480e 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -49,6 +49,49 @@ typedef struct BlockDriver BlockDriver; typedef struct BdrvChild BdrvChild; typedef struct BdrvChildClass BdrvChildClass; +typedef enum BlockZoneOp { + BLK_ZO_OPEN, + BLK_ZO_CLOSE, + BLK_ZO_FINISH, + BLK_ZO_RESET, +} BlockZoneOp; + +typedef enum BlockZoneModel { + BLK_Z_NONE = 0x0, /* Regular block device */ + BLK_Z_HM = 0x1, /* Host-managed zoned block device */ + BLK_Z_HA = 0x2, /* Host-aware zoned block device */ +} BlockZoneModel; + +typedef enum BlockZoneCondition { + BLK_ZS_NOT_WP = 0x0, + BLK_ZS_EMPTY = 0x1, + BLK_ZS_IOPEN = 0x2, + BLK_ZS_EOPEN = 0x3, + BLK_ZS_CLOSED = 0x4, + BLK_ZS_RDONLY = 0xD, + BLK_ZS_FULL = 0xE, + BLK_ZS_OFFLINE = 0xF, +} BlockZoneCondition; + +typedef enum BlockZoneType { + BLK_ZT_CONV = 0x1, /* Conventional random writes supported */ + BLK_ZT_SWR = 0x2, /* Sequential writes required */ + BLK_ZT_SWP = 0x3, /* Sequential writes preferred */ +} BlockZoneType; + +/* + * Zone descriptor data structure. + * Provides information on a zone with all position and size values in bytes. + */ +typedef struct BlockZoneDescriptor { + uint64_t start; + uint64_t length; + uint64_t cap; + uint64_t wp; + BlockZoneType type; + BlockZoneCondition cond; +} BlockZoneDescriptor; + typedef struct BlockDriverInfo { /* in bytes, 0 if irrelevant */ int cluster_size; From patchwork Sat Sep 10 05:27:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12972387 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D1EFBC6FA82 for ; Sat, 10 Sep 2022 05:42:05 +0000 (UTC) Received: from localhost ([::1]:42792 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWtFk-0003Ar-Dz for qemu-devel@archiver.kernel.org; Sat, 10 Sep 2022 01:42:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49946) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWt2t-0002CM-EF; Sat, 10 Sep 2022 01:28:47 -0400 Received: from mail-pg1-x536.google.com ([2607:f8b0:4864:20::536]:45848) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oWt2r-0004ne-K8; Sat, 10 Sep 2022 01:28:47 -0400 Received: by mail-pg1-x536.google.com with SMTP id h188so3390069pgc.12; Fri, 09 Sep 2022 22:28:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=HK20SnxvC2yqSmScJhmV/FP8kW87JPGEWe5pmoXhJX0=; b=OHVNbR9xUEWIcymjz8JD5l7XbCSdVSIUoqWIw9zuySOPYjL7kprGxVHfvDvyLVt0C9 cP0+66JOvKsLKrIWr2yDQ8aycUuh9oqLNXVfEjHkQW4iN9JncF+znJENeldzAKlyxKNr 5Ft88HZm+1073U1iTFqv+FJ2zcTP2qjG+d95TeZEbCefBmoCmfC7hnoqiUsr16jhNapJ i8TsIysMq+WFAb8KgVE7NDH4RugcjDWJCS0XRLId6kaebrpRmo2uw0PRXWr1VqEOGb8r h2i8b0l2Fjuq/prQQ2ps4Y/w6mgQYmOfCvaN5jkPRDUfvZy4bLAR+TxFyKmvGKYnY1hl RyOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=HK20SnxvC2yqSmScJhmV/FP8kW87JPGEWe5pmoXhJX0=; b=4jYCE+WyhsWbXt9uUKCrQwkmjyqCzFzG/045HmMtukdX8YdGYc2FwbSqQcc7jmgFrk uOa60dHJ9HQEortJRb0LDMCLOmAiABTaS0B3IhqUnBtJbwjX8MBCeHPoOvbAAyzX3yx4 vhaSYOgfsCd0RFTIT0aRzMhDvbUrJoPzE1pNhGE+NQt3kkyBCL42CP3mRbIpc8+rucN8 J7R6frGlUZ93JXMjMHz6J2mncO2mdE9DALM776TCaJAEzJE89eUIndCPvziLrFyx5NVo bepigp5VNQVkh1u3sAWsAMmHMtttpDFVS3j1+D0cZ+0jDNewue8V9bnvPe2wR76K941y P88g== X-Gm-Message-State: ACgBeo3V3ytGTyId4L8hMuGuDmM9iiuhq2i2THBHOFB9ww23NDL1K+Pn GSZ6IctK7n2ZYo9+e7c306mJ7eUqlTTE/8DL X-Google-Smtp-Source: AA6agR7kkOgUgHRBf01vf2P2JBuuo79SZfxiPo+W675ZqwEstzByE8M1OZVL6TY0l6ANHslCjXUCcg== X-Received: by 2002:a63:81c8:0:b0:438:919e:8256 with SMTP id t191-20020a6381c8000000b00438919e8256mr4495500pgd.39.1662787723488; Fri, 09 Sep 2022 22:28:43 -0700 (PDT) Received: from roots.. ([183.221.93.83]) by smtp.gmail.com with ESMTPSA id y6-20020aa793c6000000b00540d75197e5sm731994pff.47.2022.09.09.22.28.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Sep 2022 22:28:43 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: dmitry.fomichev@wdc.com, Markus Armbruster , Eric Blake , qemu-block@nongnu.org, Stefan Hajnoczi , Kevin Wolf , Fam Zheng , damien.lemoal@opensource.wdc.com, hare@suse.de, Hanna Reitz , Sam Li Subject: [PATCH v9 2/7] file-posix: introduce helper functions for sysfs attributes Date: Sat, 10 Sep 2022 13:27:54 +0800 Message-Id: <20220910052759.27517-3-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220910052759.27517-1-faithilikerun@gmail.com> References: <20220910052759.27517-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::536; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x536.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Use get_sysfs_str_val() to get the string value of device zoned model. Then get_sysfs_zoned_model() can convert it to BlockZoneModel type of QEMU. Use get_sysfs_long_val() to get the long value of zoned device information. Signed-off-by: Sam Li Reviewed-by: Hannes Reinecke Reviewed-by: Stefan Hajnoczi Reviewed-by: Damien Le Moal --- block/file-posix.c | 121 ++++++++++++++++++++++--------- include/block/block_int-common.h | 3 + 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index 48cd096624..0a8b4b426e 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1210,66 +1210,109 @@ static int hdev_get_max_hw_transfer(int fd, struct stat *st) #endif } -static int hdev_get_max_segments(int fd, struct stat *st) -{ +/* + * Get a sysfs attribute value as character string. + */ +static int get_sysfs_str_val(struct stat *st, const char *attribute, + char **val) { #ifdef CONFIG_LINUX - char buf[32]; - const char *end; - char *sysfspath = NULL; + g_autofree char *sysfspath = NULL; int ret; - int sysfd = -1; - long max_segments; + size_t len; - if (S_ISCHR(st->st_mode)) { - if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) { - return ret; - } + if (!S_ISBLK(st->st_mode)) { return -ENOTSUP; } - if (!S_ISBLK(st->st_mode)) { - return -ENOTSUP; + sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s", + major(st->st_rdev), minor(st->st_rdev), + attribute); + ret = g_file_get_contents(sysfspath, val, &len, NULL); + if (ret == -1) { + return -ENOENT; } - sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments", - major(st->st_rdev), minor(st->st_rdev)); - sysfd = open(sysfspath, O_RDONLY); - if (sysfd == -1) { - ret = -errno; - goto out; + /* The file is ended with '\n' */ + char *p; + p = *val; + if (*(p + len - 1) == '\n') { + *(p + len - 1) = '\0'; } - do { - ret = read(sysfd, buf, sizeof(buf) - 1); - } while (ret == -1 && errno == EINTR); + return ret; +#else + return -ENOTSUP; +#endif +} + +static int get_sysfs_zoned_model(struct stat *st, BlockZoneModel *zoned) { + g_autofree char *val = NULL; + int ret; + + ret = get_sysfs_str_val(st, "zoned", &val); if (ret < 0) { - ret = -errno; - goto out; - } else if (ret == 0) { - ret = -EIO; - goto out; + return ret; } - buf[ret] = 0; - /* The file is ended with '\n', pass 'end' to accept that. */ - ret = qemu_strtol(buf, &end, 10, &max_segments); - if (ret == 0 && end && *end == '\n') { - ret = max_segments; + + if (strcmp(val, "host-managed") == 0) { + *zoned = BLK_Z_HM; + } else if (strcmp(val, "host-aware") == 0) { + *zoned = BLK_Z_HA; + } else if (strcmp(val, "none") == 0) { + *zoned = BLK_Z_NONE; + } else { + return -ENOTSUP; } + return 0; +} -out: - if (sysfd != -1) { - close(sysfd); +/* + * Get a sysfs attribute value as a long integer. + */ +static long get_sysfs_long_val(struct stat *st, const char *attribute) { +#ifdef CONFIG_LINUX + g_autofree char *str = NULL; + const char *end; + long val; + int ret; + + ret = get_sysfs_str_val(st, attribute, &str); + if (ret < 0) { + return ret; + } + + /* The file is ended with '\n', pass 'end' to accept that. */ + ret = qemu_strtol(str, &end, 10, &val); + if (ret == 0 && end && *end == '\0') { + ret = val; } - g_free(sysfspath); return ret; #else return -ENOTSUP; #endif } +static int hdev_get_max_segments(int fd, struct stat *st) { +#ifdef CONFIG_LINUX + int ret; + + if (S_ISCHR(st->st_mode)) { + if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) { + return ret; + } + return -ENOTSUP; + } + return get_sysfs_long_val(st, "max_segments"); +#else + return -ENOTSUP; +#endif +} + static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVRawState *s = bs->opaque; struct stat st; + int ret; + BlockZoneModel zoned; s->needs_alignment = raw_needs_alignment(bs); raw_probe_alignment(bs, s->fd, errp); @@ -1307,6 +1350,12 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) bs->bl.max_hw_iov = ret; } } + + ret = get_sysfs_zoned_model(&st, &zoned); + if (ret < 0) { + zoned = BLK_Z_NONE; + } + bs->bl.zoned = zoned; } static int check_for_dasd(int fd) diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 8947abab76..7f7863cc9e 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -825,6 +825,9 @@ typedef struct BlockLimits { /* maximum number of iovec elements */ int max_iov; + + /* device zone model */ + BlockZoneModel zoned; } BlockLimits; typedef struct BdrvOpBlocker BdrvOpBlocker; From patchwork Sat Sep 10 05:27:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12972389 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C7884ECAAD5 for ; Sat, 10 Sep 2022 05:51:10 +0000 (UTC) Received: from localhost ([::1]:51356 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWtOX-0007Hc-OG for qemu-devel@archiver.kernel.org; Sat, 10 Sep 2022 01:51:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38950) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWt32-0002Iw-AV; Sat, 10 Sep 2022 01:28:56 -0400 Received: from mail-pg1-x535.google.com ([2607:f8b0:4864:20::535]:40678) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oWt2y-0004mk-US; Sat, 10 Sep 2022 01:28:56 -0400 Received: by mail-pg1-x535.google.com with SMTP id r17so3402614pgr.7; Fri, 09 Sep 2022 22:28:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=DQf9S4avJd+VwsuvpydyROH1xKQMdqcyFGexFAhCyfw=; b=bj8J+f9FBeGLuWCYqcVSsJfbGaPV8Znm17i8cXiok4YKg3K2KVbRzWfjtn6e/BFVer lXb+ixgBy5g/UCgeIR52uszqKGS3hhJwT7XzCcjtBB4fBBGyxOsJ849BcyQMnPe9EHq6 21aO10wdgQChRp2fPwplLuXNtK3nnqyxLgsY8x/H6Yc5dRLUO4IHBIzc/rxXCA/BGw5b MBhNTT6LuWFNlNvJILZ/yADMTR0xrJwX4UUEwMfUzitZxfK0Kriu2B2FV0Znp0Ag96oV PZVoe/OnN4RVjMBvHTcP96g70Vuex3RUGYr3XOeXXclL5+5m6YrtzldZVlqYITxu+eXs zLaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=DQf9S4avJd+VwsuvpydyROH1xKQMdqcyFGexFAhCyfw=; b=weGL91mlLBpxom4ElZsvjazTVaFSBfeviS4V0fRlgtcTmeljtao6qPnsbOIsbLfQVk 7989bFo1gTeRcTfZJX8adOw+uZNTBxDK6dRFlluJTI/hjRItvZr6nnSrH6H8OyMH+Ivt fDjJqU3I5TPThse/Sm4Wm0Re5qO0wVlYJnIr7OXliLUS/g1cSxCM45tNtD50Lx1NhJ5Q yPIgK1p9cHRsBdaMXespL5rTWR3qZFzs9nFQVWPmk5IsFZKz6W9F7U7XtXFZ5a4obRgu /XMHiM3ej2qNR/58lQ7kRnP6WnRsrr4MTg95D+ZXZ0oUT6W35W+IT3LgsosOaCGlNqIe mhGg== X-Gm-Message-State: ACgBeo3PhS6FYjzSMsww09mz6VR52K6PV6kZpbBugj9aTzSEWmR1hBIs wyTqizCRv4qjNWMUcYc7QahzO/Pnfgd6bTpC X-Google-Smtp-Source: AA6agR5nBcoiU3R1J+r8U3lQsPq/OsbdWlslYQWtP5NZpAplBGsUeom486au5C1B02BBz1zSRnkQmQ== X-Received: by 2002:a62:1c81:0:b0:52f:ccb5:9de1 with SMTP id c123-20020a621c81000000b0052fccb59de1mr17409792pfc.45.1662787731328; Fri, 09 Sep 2022 22:28:51 -0700 (PDT) Received: from roots.. ([183.221.93.83]) by smtp.gmail.com with ESMTPSA id y6-20020aa793c6000000b00540d75197e5sm731994pff.47.2022.09.09.22.28.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Sep 2022 22:28:51 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: dmitry.fomichev@wdc.com, Markus Armbruster , Eric Blake , qemu-block@nongnu.org, Stefan Hajnoczi , Kevin Wolf , Fam Zheng , damien.lemoal@opensource.wdc.com, hare@suse.de, Hanna Reitz , Sam Li Subject: [PATCH v9 3/7] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls Date: Sat, 10 Sep 2022 13:27:55 +0800 Message-Id: <20220910052759.27517-4-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220910052759.27517-1-faithilikerun@gmail.com> References: <20220910052759.27517-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::535; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x535.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add a new zoned_host_device BlockDriver. The zoned_host_device option accepts only zoned host block devices. By adding zone management operations in this new BlockDriver, users can use the new block layer APIs including Report Zone and four zone management operations (open, close, finish, reset). Qemu-io uses the new APIs to perform zoned storage commands of the device: zone_report(zrp), zone_open(zo), zone_close(zc), zone_reset(zrs), zone_finish(zf). For example, to test zone_report, use following command: $ ./build/qemu-io --image-opts -n driver=zoned_host_device, filename=/dev/nullb0 -c "zrp offset nr_zones" Signed-off-by: Sam Li Reviewed-by: Hannes Reinecke --- block/block-backend.c | 145 ++++++++++++++ block/file-posix.c | 323 +++++++++++++++++++++++++++++- block/io.c | 41 ++++ include/block/block-io.h | 7 + include/block/block_int-common.h | 21 ++ include/block/raw-aio.h | 6 +- include/sysemu/block-backend-io.h | 17 ++ meson.build | 1 + qapi/block-core.json | 8 +- qemu-io-cmds.c | 143 +++++++++++++ 10 files changed, 708 insertions(+), 4 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index d4a5df2ac2..ebe8d7bdf3 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1431,6 +1431,15 @@ typedef struct BlkRwCo { void *iobuf; int ret; BdrvRequestFlags flags; + union { + struct { + unsigned int *nr_zones; + BlockZoneDescriptor *zones; + } zone_report; + struct { + BlockZoneOp op; + } zone_mgmt; + }; } BlkRwCo; int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags) @@ -1775,6 +1784,142 @@ int coroutine_fn blk_co_flush(BlockBackend *blk) return ret; } +static void blk_aio_zone_report_entry(void *opaque) { + BlkAioEmAIOCB *acb = opaque; + BlkRwCo *rwco = &acb->rwco; + + rwco->ret = blk_co_zone_report(rwco->blk, rwco->offset, + rwco->zone_report.nr_zones, + rwco->zone_report.zones); + blk_aio_complete(acb); +} + +BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones, + BlockCompletionFunc *cb, void *opaque) +{ + BlkAioEmAIOCB *acb; + Coroutine *co; + IO_CODE(); + + blk_inc_in_flight(blk); + acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); + acb->rwco = (BlkRwCo) { + .blk = blk, + .offset = offset, + .ret = NOT_DONE, + .zone_report = { + .zones = zones, + .nr_zones = nr_zones, + }, + }; + acb->has_returned = false; + + co = qemu_coroutine_create(blk_aio_zone_report_entry, acb); + bdrv_coroutine_enter(blk_bs(blk), co); + + acb->has_returned = true; + if (acb->rwco.ret != NOT_DONE) { + replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), + blk_aio_complete_bh, acb); + } + + return &acb->common; +} + +static void blk_aio_zone_mgmt_entry(void *opaque) { + BlkAioEmAIOCB *acb = opaque; + BlkRwCo *rwco = &acb->rwco; + + rwco->ret = blk_co_zone_mgmt(rwco->blk, rwco->zone_mgmt.op, + rwco->offset, acb->bytes); + blk_aio_complete(acb); +} + +BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op, + int64_t offset, int64_t len, + BlockCompletionFunc *cb, void *opaque) { + BlkAioEmAIOCB *acb; + Coroutine *co; + IO_CODE(); + + blk_inc_in_flight(blk); + acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque); + acb->rwco = (BlkRwCo) { + .blk = blk, + .offset = offset, + .ret = NOT_DONE, + .zone_mgmt = { + .op = op, + }, + }; + acb->bytes = len; + acb->has_returned = false; + + co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb); + bdrv_coroutine_enter(blk_bs(blk), co); + + acb->has_returned = true; + if (acb->rwco.ret != NOT_DONE) { + replay_bh_schedule_oneshot_event(blk_get_aio_context(blk), + blk_aio_complete_bh, acb); + } + + return &acb->common; +} + +/* + * Send a zone_report command. + * offset is a byte offset from the start of the device. No alignment + * required for offset. + * nr_zones represents IN maximum and OUT actual. + */ +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones) +{ + int ret; + IO_CODE(); + + blk_inc_in_flight(blk); /* increase before waiting */ + blk_wait_while_drained(blk); + if (!blk_is_available(blk)) { + blk_dec_in_flight(blk); + return -ENOMEDIUM; + } + ret = bdrv_co_zone_report(blk_bs(blk), offset, nr_zones, zones); + blk_dec_in_flight(blk); + return ret; +} + +/* + * Send a zone_management command. + * op is the zone operation; + * offset is the byte offset from the start of the zoned device; + * len is the maximum number of bytes the command should operate on. It + * should be aligned with the zone sector size. + */ +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op, + int64_t offset, int64_t len) +{ + int ret; + IO_CODE(); + + + blk_inc_in_flight(blk); + blk_wait_while_drained(blk); + + ret = blk_check_byte_request(blk, offset, len); + if (ret < 0) { + return ret; + } + + ret = bdrv_co_zone_mgmt(blk_bs(blk), op, offset, len); + blk_dec_in_flight(blk); + return ret; +} + void blk_drain(BlockBackend *blk) { BlockDriverState *bs = blk_bs(blk); diff --git a/block/file-posix.c b/block/file-posix.c index 0a8b4b426e..4edfa25d04 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -67,6 +67,9 @@ #include #include #include +#if defined(CONFIG_BLKZONED) +#include +#endif #include #include #include @@ -216,6 +219,15 @@ typedef struct RawPosixAIOData { PreallocMode prealloc; Error **errp; } truncate; + struct { + unsigned int *nr_zones; + BlockZoneDescriptor *zones; + } zone_report; + struct { + unsigned long zone_op; + const char *zone_op_name; + bool all; + } zone_mgmt; }; } RawPosixAIOData; @@ -1339,7 +1351,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) #endif if (bs->sg || S_ISBLK(st.st_mode)) { - int ret = hdev_get_max_hw_transfer(s->fd, &st); + ret = hdev_get_max_hw_transfer(s->fd, &st); if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) { bs->bl.max_hw_transfer = ret; @@ -1356,6 +1368,27 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) zoned = BLK_Z_NONE; } bs->bl.zoned = zoned; + if (zoned != BLK_Z_NONE) { + ret = get_sysfs_long_val(&st, "chunk_sectors"); + if (ret > 0) { + bs->bl.zone_sectors = ret; + } + + ret = get_sysfs_long_val(&st, "zone_append_max_bytes"); + if (ret > 0) { + bs->bl.max_append_sectors = ret / 512; + } + + ret = get_sysfs_long_val(&st, "max_open_zones"); + if (ret >= 0) { + bs->bl.max_open_zones = ret; + } + + ret = get_sysfs_long_val(&st, "max_active_zones"); + if (ret >= 0) { + bs->bl.max_active_zones = ret; + } + } } static int check_for_dasd(int fd) @@ -1850,6 +1883,145 @@ static off_t copy_file_range(int in_fd, off_t *in_off, int out_fd, } #endif +/* + * parse_zone - Fill a zone descriptor + */ +#if defined(CONFIG_BLKZONED) +static inline void parse_zone(struct BlockZoneDescriptor *zone, + const struct blk_zone *blkz) { + zone->start = blkz->start; + zone->length = blkz->len; + zone->cap = blkz->capacity; + zone->wp = blkz->wp; + + switch (blkz->type) { + case BLK_ZONE_TYPE_SEQWRITE_REQ: + zone->type = BLK_ZT_SWR; + break; + case BLK_ZONE_TYPE_SEQWRITE_PREF: + zone->type = BLK_ZT_SWP; + break; + case BLK_ZONE_TYPE_CONVENTIONAL: + zone->type = BLK_ZT_CONV; + break; + default: + g_assert_not_reached(); + } + + switch (blkz->cond) { + case BLK_ZONE_COND_NOT_WP: + zone->cond = BLK_ZS_NOT_WP; + break; + case BLK_ZONE_COND_EMPTY: + zone->cond = BLK_ZS_EMPTY; + break; + case BLK_ZONE_COND_IMP_OPEN: + zone->cond =BLK_ZS_IOPEN; + break; + case BLK_ZONE_COND_EXP_OPEN: + zone->cond = BLK_ZS_EOPEN; + break; + case BLK_ZONE_COND_CLOSED: + zone->cond = BLK_ZS_CLOSED; + break; + case BLK_ZONE_COND_READONLY: + zone->cond = BLK_ZS_RDONLY; + break; + case BLK_ZONE_COND_FULL: + zone->cond = BLK_ZS_FULL; + break; + case BLK_ZONE_COND_OFFLINE: + zone->cond = BLK_ZS_OFFLINE; + break; + default: + g_assert_not_reached(); + } +} +#endif + +#if defined(CONFIG_BLKZONED) +static int do_zone_report(int64_t sector, int fd, + struct BlockZoneDescriptor *zones, + unsigned int nrz) { + struct blk_zone *blkz; + int ret, n = 0, i = 0; + + int64_t rep_size = sizeof(struct blk_zone_report) + nrz * sizeof(struct blk_zone); + g_autofree struct blk_zone_report *rep = NULL; + rep = g_malloc(rep_size); + + blkz = (struct blk_zone *)(rep + 1); + while (n < nrz) { + memset(rep, 0, rep_size); + rep->sector = sector; + rep->nr_zones = nrz - n; + + do { + ret = ioctl(fd, BLKREPORTZONE, rep); + } while (ret != 0 && errno == EINTR); + if (ret != 0) { + error_report("%d: ioctl BLKREPORTZONE at %" PRId64 " failed %d", + fd, sector, errno); + return -errno; + } + + if (!rep->nr_zones) { + break; + } + + for (i = 0; i < rep->nr_zones; i++, n++) { + parse_zone(&zones[n], &blkz[i]); + /* The next report should start after the last zone reported */ + sector = blkz[i].start + blkz[i].len; + } + } + return n; +} +#endif + +static int handle_aiocb_zone_report(void *opaque) { +#if defined(CONFIG_BLKZONED) + RawPosixAIOData *aiocb = opaque; + int fd = aiocb->aio_fildes; + unsigned int *nr_zones = aiocb->zone_report.nr_zones; + BlockZoneDescriptor *zones = aiocb->zone_report.zones; + /* zoned block devices use 512-byte sectors */ + int64_t sector = aiocb->aio_offset / 512; + + *nr_zones = do_zone_report(sector, fd, zones, *nr_zones); + return 0; +#else + return -ENOTSUP; +#endif +} + +static int handle_aiocb_zone_mgmt(void *opaque) { +#if defined(CONFIG_BLKZONED) + RawPosixAIOData *aiocb = opaque; + int fd = aiocb->aio_fildes; + int64_t sector = aiocb->aio_offset / 512; + int64_t nr_sectors = aiocb->aio_nbytes / 512; + struct blk_zone_range range; + int ret; + + /* Execute the operation */ + range.sector = sector; + range.nr_sectors = nr_sectors; + do { + ret = ioctl(fd, aiocb->zone_mgmt.zone_op, &range); + } while (ret != 0 && errno == EINTR); + + if (ret != 0) { + error_report("ioctl %s failed %d", aiocb->zone_mgmt.zone_op_name, + errno); + return -errno; + } + return ret; +#else + return -ENOTSUP; +#endif +} + static int handle_aiocb_copy_range(void *opaque) { RawPosixAIOData *aiocb = opaque; @@ -3022,6 +3194,104 @@ static void raw_account_discard(BDRVRawState *s, uint64_t nbytes, int ret) } } +/* + * zone report - Get a zone block device's information in the form + * of an array of zone descriptors. + * zones is an array of zone descriptors to hold zone information on reply; + * offset can be any byte within the entire size of the device; + * nr_zones is the maxium number of sectors the command should operate on. + */ +static int coroutine_fn raw_co_zone_report(BlockDriverState *bs, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones) { +#if defined(CONFIG_BLKZONED) + BDRVRawState *s = bs->opaque; + RawPosixAIOData acb; + + acb = (RawPosixAIOData) { + .bs = bs, + .aio_fildes = s->fd, + .aio_type = QEMU_AIO_ZONE_REPORT, + .aio_offset = offset, + .zone_report = { + .nr_zones = nr_zones, + .zones = zones, + }, + }; + + return raw_thread_pool_submit(bs, handle_aiocb_zone_report, &acb); +#else + return -ENOTSUP; +#endif +} + +/* + * zone management operations - Execute an operation on a zone + */ +static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, + int64_t offset, int64_t len) { +#if defined(CONFIG_BLKZONED) + BDRVRawState *s = bs->opaque; + RawPosixAIOData acb; + int64_t zone_sector, zone_sector_mask; + const char *zone_op_name; + unsigned long zone_op; + bool is_all = false; + + zone_sector = bs->bl.zone_sectors; + zone_sector_mask = zone_sector - 1; + if (offset & zone_sector_mask) { + error_report("sector offset %" PRId64 " is not aligned to zone size " + "%" PRId64 "", offset, zone_sector); + return -EINVAL; + } + + if (len & zone_sector_mask) { + error_report("number of sectors %" PRId64 " is not aligned to zone size" + " %" PRId64 "", len, zone_sector); + return -EINVAL; + } + + switch (op) { + case BLK_ZO_OPEN: + zone_op_name = "BLKOPENZONE"; + zone_op = BLKOPENZONE; + break; + case BLK_ZO_CLOSE: + zone_op_name = "BLKCLOSEZONE"; + zone_op = BLKCLOSEZONE; + break; + case BLK_ZO_FINISH: + zone_op_name = "BLKFINISHZONE"; + zone_op = BLKFINISHZONE; + break; + case BLK_ZO_RESET: + zone_op_name = "BLKRESETZONE"; + zone_op = BLKRESETZONE; + break; + default: + g_assert_not_reached(); + } + + acb = (RawPosixAIOData) { + .bs = bs, + .aio_fildes = s->fd, + .aio_type = QEMU_AIO_ZONE_MGMT, + .aio_offset = offset, + .aio_nbytes = len, + .zone_mgmt = { + .zone_op = zone_op, + .zone_op_name = zone_op_name, + .all = is_all, + }, + }; + + return raw_thread_pool_submit(bs, handle_aiocb_zone_mgmt, &acb); +#else + return -ENOTSUP; +#endif +} + static coroutine_fn int raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes, bool blkdev) @@ -3752,6 +4022,54 @@ static BlockDriver bdrv_host_device = { #endif }; +#if defined(CONFIG_BLKZONED) +static BlockDriver bdrv_zoned_host_device = { + .format_name = "zoned_host_device", + .protocol_name = "zoned_host_device", + .instance_size = sizeof(BDRVRawState), + .bdrv_needs_filename = true, + .bdrv_probe_device = hdev_probe_device, + .bdrv_file_open = hdev_open, + .bdrv_close = raw_close, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, + .bdrv_co_create_opts = bdrv_co_create_opts_simple, + .create_opts = &bdrv_create_opts_simple, + .mutable_opts = mutable_opts, + .bdrv_co_invalidate_cache = raw_co_invalidate_cache, + .bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes, + + .bdrv_co_preadv = raw_co_preadv, + .bdrv_co_pwritev = raw_co_pwritev, + .bdrv_co_flush_to_disk = raw_co_flush_to_disk, + .bdrv_co_pdiscard = hdev_co_pdiscard, + .bdrv_co_copy_range_from = raw_co_copy_range_from, + .bdrv_co_copy_range_to = raw_co_copy_range_to, + .bdrv_refresh_limits = raw_refresh_limits, + .bdrv_io_plug = raw_aio_plug, + .bdrv_io_unplug = raw_aio_unplug, + .bdrv_attach_aio_context = raw_aio_attach_aio_context, + + .bdrv_co_truncate = raw_co_truncate, + .bdrv_getlength = raw_getlength, + .bdrv_get_info = raw_get_info, + .bdrv_get_allocated_file_size + = raw_get_allocated_file_size, + .bdrv_get_specific_stats = hdev_get_specific_stats, + .bdrv_check_perm = raw_check_perm, + .bdrv_set_perm = raw_set_perm, + .bdrv_abort_perm_update = raw_abort_perm_update, + .bdrv_probe_blocksizes = hdev_probe_blocksizes, + .bdrv_probe_geometry = hdev_probe_geometry, + .bdrv_co_ioctl = hdev_co_ioctl, + + /* zone management operations */ + .bdrv_co_zone_report = raw_co_zone_report, + .bdrv_co_zone_mgmt = raw_co_zone_mgmt, +}; +#endif + #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) static void cdrom_parse_filename(const char *filename, QDict *options, Error **errp) @@ -4012,6 +4330,9 @@ static void bdrv_file_init(void) bdrv_register(&bdrv_file); #if defined(HAVE_HOST_BLOCK_DEVICE) bdrv_register(&bdrv_host_device); +#if defined(CONFIG_BLKZONED) + bdrv_register(&bdrv_zoned_host_device); +#endif #ifdef __linux__ bdrv_register(&bdrv_host_cdrom); #endif diff --git a/block/io.c b/block/io.c index 0a8cbefe86..de9ec1d740 100644 --- a/block/io.c +++ b/block/io.c @@ -3198,6 +3198,47 @@ out: return co.ret; } +int bdrv_co_zone_report(BlockDriverState *bs, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones) +{ + BlockDriver *drv = bs->drv; + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + IO_CODE(); + + bdrv_inc_in_flight(bs); + if (!drv || !drv->bdrv_co_zone_report) { + co.ret = -ENOTSUP; + goto out; + } + co.ret = drv->bdrv_co_zone_report(bs, offset, nr_zones, zones); +out: + bdrv_dec_in_flight(bs); + return co.ret; +} + +int bdrv_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, + int64_t offset, int64_t len) +{ + BlockDriver *drv = bs->drv; + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + IO_CODE(); + + bdrv_inc_in_flight(bs); + if (!drv || !drv->bdrv_co_zone_mgmt) { + co.ret = -ENOTSUP; + goto out; + } + co.ret = drv->bdrv_co_zone_mgmt(bs, op, offset, len); +out: + bdrv_dec_in_flight(bs); + return co.ret; +} + void *qemu_blockalign(BlockDriverState *bs, size_t size) { IO_CODE(); diff --git a/include/block/block-io.h b/include/block/block-io.h index fd25ffa9be..65463b88d9 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -88,6 +88,13 @@ int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); /* Ensure contents are flushed to disk. */ int coroutine_fn bdrv_co_flush(BlockDriverState *bs); +/* Report zone information of zone block device. */ +int coroutine_fn bdrv_co_zone_report(BlockDriverState *bs, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones); +int coroutine_fn bdrv_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, + int64_t offset, int64_t len); + int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes); bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); int bdrv_block_status(BlockDriverState *bs, int64_t offset, diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 7f7863cc9e..078ddd7e67 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -691,6 +691,12 @@ struct BlockDriver { QEMUIOVector *qiov, int64_t pos); + int coroutine_fn (*bdrv_co_zone_report)(BlockDriverState *bs, + int64_t offset, unsigned int *nr_zones, + BlockZoneDescriptor *zones); + int coroutine_fn (*bdrv_co_zone_mgmt)(BlockDriverState *bs, BlockZoneOp op, + int64_t offset, int64_t len); + /* removable device specific */ bool (*bdrv_is_inserted)(BlockDriverState *bs); void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag); @@ -828,6 +834,21 @@ typedef struct BlockLimits { /* device zone model */ BlockZoneModel zoned; + + /* zone size expressed in 512-byte sectors */ + uint32_t zone_sectors; + + /* total number of zones */ + unsigned int nr_zones; + + /* maximum sectors of a zone append write operation */ + int64_t max_append_sectors; + + /* maximum number of open zones */ + int64_t max_open_zones; + + /* maximum number of active zones */ + int64_t max_active_zones; } BlockLimits; typedef struct BdrvOpBlocker BdrvOpBlocker; diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h index 21fc10c4c9..3d26929cdd 100644 --- a/include/block/raw-aio.h +++ b/include/block/raw-aio.h @@ -29,6 +29,8 @@ #define QEMU_AIO_WRITE_ZEROES 0x0020 #define QEMU_AIO_COPY_RANGE 0x0040 #define QEMU_AIO_TRUNCATE 0x0080 +#define QEMU_AIO_ZONE_REPORT 0x0100 +#define QEMU_AIO_ZONE_MGMT 0x0200 #define QEMU_AIO_TYPE_MASK \ (QEMU_AIO_READ | \ QEMU_AIO_WRITE | \ @@ -37,7 +39,9 @@ QEMU_AIO_DISCARD | \ QEMU_AIO_WRITE_ZEROES | \ QEMU_AIO_COPY_RANGE | \ - QEMU_AIO_TRUNCATE) + QEMU_AIO_TRUNCATE | \ + QEMU_AIO_ZONE_REPORT | \ + QEMU_AIO_ZONE_MGMT) /* AIO flags */ #define QEMU_AIO_MISALIGNED 0x1000 diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h index 50f5aa2e07..6835525582 100644 --- a/include/sysemu/block-backend-io.h +++ b/include/sysemu/block-backend-io.h @@ -45,6 +45,12 @@ BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset, BlockCompletionFunc *cb, void *opaque); BlockAIOCB *blk_aio_flush(BlockBackend *blk, BlockCompletionFunc *cb, void *opaque); +BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset, + unsigned int *nr_zones, BlockZoneDescriptor *zones, + BlockCompletionFunc *cb, void *opaque); +BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op, + int64_t offset, int64_t len, + BlockCompletionFunc *cb, void *opaque); BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes, BlockCompletionFunc *cb, void *opaque); void blk_aio_cancel_async(BlockAIOCB *acb); @@ -156,6 +162,17 @@ int generated_co_wrapper blk_pwrite_zeroes(BlockBackend *blk, int64_t offset, int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, int64_t bytes, BdrvRequestFlags flags); +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones); +int generated_co_wrapper blk_zone_report(BlockBackend *blk, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones); +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op, + int64_t offset, int64_t len); +int generated_co_wrapper blk_zone_mgmt(BlockBackend *blk, BlockZoneOp op, + int64_t offset, int64_t len); + int generated_co_wrapper blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes); int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset, diff --git a/meson.build b/meson.build index 20fddbd707..2f436bb355 100644 --- a/meson.build +++ b/meson.build @@ -1883,6 +1883,7 @@ config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').al # has_header config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) +config_host_data.set('CONFIG_BLKZONED', cc.has_header('linux/blkzoned.h')) config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) diff --git a/qapi/block-core.json b/qapi/block-core.json index 2173e7734a..c6bbb7a037 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2942,6 +2942,7 @@ # @compress: Since 5.0 # @copy-before-write: Since 6.2 # @snapshot-access: Since 7.0 +# @zoned_host_device: Since 7.2 # # Since: 2.9 ## @@ -2955,7 +2956,8 @@ 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd', { 'name': 'replication', 'if': 'CONFIG_REPLICATION' }, - 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] } + 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', + { 'name': 'zoned_host_device', 'if': 'CONFIG_BLKZONED' } ] } ## # @BlockdevOptionsFile: @@ -4329,7 +4331,9 @@ 'vhdx': 'BlockdevOptionsGenericFormat', 'vmdk': 'BlockdevOptionsGenericCOWFormat', 'vpc': 'BlockdevOptionsGenericFormat', - 'vvfat': 'BlockdevOptionsVVFAT' + 'vvfat': 'BlockdevOptionsVVFAT', + 'zoned_host_device': { 'type': 'BlockdevOptionsFile', + 'if': 'CONFIG_BLKZONED' } } } ## diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 952dc940f1..446a059603 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1712,6 +1712,144 @@ static const cmdinfo_t flush_cmd = { .oneline = "flush all in-core file state to disk", }; +static int zone_report_f(BlockBackend *blk, int argc, char **argv) +{ + int ret; + int64_t offset; + unsigned int nr_zones; + + ++optind; + offset = cvtnum(argv[optind]); + ++optind; + nr_zones = cvtnum(argv[optind]); + + g_autofree BlockZoneDescriptor *zones = NULL; + zones = g_new(BlockZoneDescriptor, nr_zones); + ret = blk_zone_report(blk, offset, &nr_zones, zones); + if (ret < 0) { + printf("zone report failed: %s\n", strerror(-ret)); + } else { + for (int i = 0; i < nr_zones; ++i) { + printf("start: 0x%" PRIx64 ", len 0x%" PRIx64 ", " + "cap"" 0x%" PRIx64 ", wptr 0x%" PRIx64 ", " + "zcond:%u, [type: %u]\n", + zones[i].start, zones[i].length, zones[i].cap, zones[i].wp, + zones[i].cond, zones[i].type); + } + } + return ret; +} + +static const cmdinfo_t zone_report_cmd = { + .name = "zone_report", + .altname = "zrp", + .cfunc = zone_report_f, + .argmin = 2, + .argmax = 2, + .args = "offset number", + .oneline = "report zone information", +}; + +static int zone_open_f(BlockBackend *blk, int argc, char **argv) +{ + int ret; + int64_t offset, len; + ++optind; + offset = cvtnum(argv[optind]); + ++optind; + len = cvtnum(argv[optind]); + ret = blk_zone_mgmt(blk, BLK_ZO_OPEN, offset, len); + if (ret < 0) { + printf("zone open failed: %s\n", strerror(-ret)); + } + return ret; +} + +static const cmdinfo_t zone_open_cmd = { + .name = "zone_open", + .altname = "zo", + .cfunc = zone_open_f, + .argmin = 2, + .argmax = 2, + .args = "offset len", + .oneline = "explicit open a range of zones in zone block device", +}; + +static int zone_close_f(BlockBackend *blk, int argc, char **argv) +{ + int ret; + int64_t offset, len; + ++optind; + offset = cvtnum(argv[optind]); + ++optind; + len = cvtnum(argv[optind]); + ret = blk_zone_mgmt(blk, BLK_ZO_CLOSE, offset, len); + if (ret < 0) { + printf("zone close failed: %s\n", strerror(-ret)); + } + return ret; +} + +static const cmdinfo_t zone_close_cmd = { + .name = "zone_close", + .altname = "zc", + .cfunc = zone_close_f, + .argmin = 2, + .argmax = 2, + .args = "offset len", + .oneline = "close a range of zones in zone block device", +}; + +static int zone_finish_f(BlockBackend *blk, int argc, char **argv) +{ + int ret; + int64_t offset, len; + ++optind; + offset = cvtnum(argv[optind]); + ++optind; + len = cvtnum(argv[optind]); + ret = blk_zone_mgmt(blk, BLK_ZO_FINISH, offset, len); + if (ret < 0) { + printf("zone finish failed: %s\n", strerror(-ret)); + } + return ret; +} + +static const cmdinfo_t zone_finish_cmd = { + .name = "zone_finish", + .altname = "zf", + .cfunc = zone_finish_f, + .argmin = 2, + .argmax = 2, + .args = "offset len", + .oneline = "finish a range of zones in zone block device", +}; + +static int zone_reset_f(BlockBackend *blk, int argc, char **argv) +{ + int ret; + int64_t offset, len; + ++optind; + offset = cvtnum(argv[optind]); + ++optind; + len = cvtnum(argv[optind]); + ret = blk_zone_mgmt(blk, BLK_ZO_RESET, offset, len); + if (ret < 0) { + printf("zone reset failed: %s\n", strerror(-ret)); + } + return ret; +} + +static const cmdinfo_t zone_reset_cmd = { + .name = "zone_reset", + .altname = "zrs", + .cfunc = zone_reset_f, + .argmin = 2, + .argmax = 2, + .args = "offset len", + .oneline = "reset a zone write pointer in zone block device", +}; + static int truncate_f(BlockBackend *blk, int argc, char **argv); static const cmdinfo_t truncate_cmd = { .name = "truncate", @@ -2504,6 +2642,11 @@ static void __attribute((constructor)) init_qemuio_commands(void) qemuio_add_command(&aio_write_cmd); qemuio_add_command(&aio_flush_cmd); qemuio_add_command(&flush_cmd); + qemuio_add_command(&zone_report_cmd); + qemuio_add_command(&zone_open_cmd); + qemuio_add_command(&zone_close_cmd); + qemuio_add_command(&zone_finish_cmd); + qemuio_add_command(&zone_reset_cmd); qemuio_add_command(&truncate_cmd); qemuio_add_command(&length_cmd); qemuio_add_command(&info_cmd); From patchwork Sat Sep 10 05:27:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12972384 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9D0C0C6FA82 for ; Sat, 10 Sep 2022 05:31:49 +0000 (UTC) Received: from localhost ([::1]:46740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWt5o-0005JQ-Lp for qemu-devel@archiver.kernel.org; Sat, 10 Sep 2022 01:31:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38952) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWt39-0002UA-8B; Sat, 10 Sep 2022 01:29:03 -0400 Received: from mail-pg1-x529.google.com ([2607:f8b0:4864:20::529]:39720) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oWt36-0004o9-Kj; Sat, 10 Sep 2022 01:29:02 -0400 Received: by mail-pg1-x529.google.com with SMTP id q9so3407903pgq.6; Fri, 09 Sep 2022 22:28:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=7O+QsLYhZ8Both8Npds514XyHYENJSnHFw3FwkAI85w=; b=gH8XlP9KlEfzTRdeJKSygrLmj9Q11mQP8cTqvaYabj6PrVxRh16qo8qfW8wsYoacSw lYHBjj3gPPvCVJVoWc/7BbDF8GvaNLYYlXj0zDkbK5mlAg1QnBa/kLqp4CpjRxpvxdvo BXqJUZnjzThCPVlvuV55e+5FOXpgHFHe+4IZa8ikop2+G++j/IXrIP/NrC3m2NJm6Lgh lCUph+XMhbTYVO1PMqaDX7JjAweS6n4Acz0RZpOGO1bEPZOxbkwempopcWPPdXses16z raY6aSoEluCMR21huuJ2Q0/MDMAK4lQBWBg6cLkBjFaAfzAzk6zxTwQqXsW5v0xLF+jl rJQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=7O+QsLYhZ8Both8Npds514XyHYENJSnHFw3FwkAI85w=; b=xS/xsSv5LzMFWAl6gTwLJY21aCZS9x8cv0sm+EP484Fe1vkRiRKecIZdgIxZhmVypP 43Nvlex1dDFNRj6qKE1sBb/1fQXp3hjLIGVjHDD70GEecKLvAN5ex/BBLaWNXB4adOIa c82l34ughJNgUKHdKUL9dfr/ttZfAWtJZqvbMzo2G+7H6N7Ji1doeMQ4GDLOXXDhFOEK SVX/pPLoFmEFyvNxQSz7uPN/D6BF6uhX2GP2DHW3kavJzde6SpXb3NXr4MM9vtxNu7XL l/MFmMyG+ajUTp8F10PrW3YWFUxfuXllv2IAYftL+VDAOm0jm9uooCgGv8UWlf1GzxXD XTcQ== X-Gm-Message-State: ACgBeo3sg+LiFVC2L6hVRVM6Q8QowDcScKNo7SgiicMWo48Iu1yAYYA+ wMuuNUloxzzK54K6ZNAuiPzRnHUwy31c8pQT X-Google-Smtp-Source: AA6agR5T9vACLoRG8rcXpWX1bmDis7vq1o3Q6PTllxt3RoZv4KY0Fi8uIl3BWETaxIJJiO0Wryi1FA== X-Received: by 2002:a63:4519:0:b0:434:ae87:ca5b with SMTP id s25-20020a634519000000b00434ae87ca5bmr15074881pga.194.1662787738672; Fri, 09 Sep 2022 22:28:58 -0700 (PDT) Received: from roots.. ([183.221.93.83]) by smtp.gmail.com with ESMTPSA id y6-20020aa793c6000000b00540d75197e5sm731994pff.47.2022.09.09.22.28.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Sep 2022 22:28:58 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: dmitry.fomichev@wdc.com, Markus Armbruster , Eric Blake , qemu-block@nongnu.org, Stefan Hajnoczi , Kevin Wolf , Fam Zheng , damien.lemoal@opensource.wdc.com, hare@suse.de, Hanna Reitz , Sam Li Subject: [PATCH v9 4/7] raw-format: add zone operations to pass through requests Date: Sat, 10 Sep 2022 13:27:56 +0800 Message-Id: <20220910052759.27517-5-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220910052759.27517-1-faithilikerun@gmail.com> References: <20220910052759.27517-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::529; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x529.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" raw-format driver usually sits on top of file-posix driver. It needs to pass through requests of zone commands. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi Reviewed-by: Damien Le Moal --- block/raw-format.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/block/raw-format.c b/block/raw-format.c index 69fd650eaf..6b20bd22ef 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -314,6 +314,17 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs, return bdrv_co_pdiscard(bs->file, offset, bytes); } +static int coroutine_fn raw_co_zone_report(BlockDriverState *bs, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones) { + return bdrv_co_zone_report(bs->file->bs, offset, nr_zones, zones); +} + +static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, + int64_t offset, int64_t len) { + return bdrv_co_zone_mgmt(bs->file->bs, op, offset, len); +} + static int64_t raw_getlength(BlockDriverState *bs) { int64_t len; @@ -614,6 +625,8 @@ BlockDriver bdrv_raw = { .bdrv_co_pwritev = &raw_co_pwritev, .bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes, .bdrv_co_pdiscard = &raw_co_pdiscard, + .bdrv_co_zone_report = &raw_co_zone_report, + .bdrv_co_zone_mgmt = &raw_co_zone_mgmt, .bdrv_co_block_status = &raw_co_block_status, .bdrv_co_copy_range_from = &raw_co_copy_range_from, .bdrv_co_copy_range_to = &raw_co_copy_range_to, From patchwork Sat Sep 10 05:27:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12972392 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9DD2DECAAD5 for ; Sat, 10 Sep 2022 05:59:38 +0000 (UTC) Received: from localhost ([::1]:47348 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWtWj-0004fS-Ad for qemu-devel@archiver.kernel.org; Sat, 10 Sep 2022 01:59:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49734) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWt3F-0002hg-N7; Sat, 10 Sep 2022 01:29:09 -0400 Received: from mail-pf1-x433.google.com ([2607:f8b0:4864:20::433]:38622) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oWt3D-0004om-TG; Sat, 10 Sep 2022 01:29:09 -0400 Received: by mail-pf1-x433.google.com with SMTP id y127so3549761pfy.5; Fri, 09 Sep 2022 22:29:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=WersfKtJfq9RRX6LalJZUvf6ogtYBj2HxLF2mLcz/E0=; b=PeWxprVFaVaQHBOuTlI4DRfPJX6we43xxADEgc2AZXnCZa3A+cEZYCc5RhfaPUJLH1 Yxp1j2TLIM2n4LXsF9LozSKbIb06I2bqx62OiXT/1bUhBNW7I1FK0zierCJX2nJnmQmH eMVdfKyCzXqGPT3zs84vmJHxjYoSdH9UHMQYl1zsg4BDakGoQNI+kfRtbrZfAj7tdwWK jl5VQBvsoPh8LQA/MuQEoBHEJFgX5zsbVv0f+Aldqyr5OTnbS9t2tZCc8ngZ3HfO3W3C iRwE5PoQ1w7528KRBRxcyBMMfmbfu6OWisjINIQ+r6BVYwwjKB31/NluAexNNyU4oAfM 7MiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=WersfKtJfq9RRX6LalJZUvf6ogtYBj2HxLF2mLcz/E0=; b=sW2Vs6tauy+rU7iemLw1+nyc3exlfVwsr0YLzlRPShU4t8cdssul2/bXKi8sRGHw2y 2UfcbJFzHm0hZsxyoqLf5bYioHELu5Eads5MKhpDmwivEIKFTkexwxcNTHf7x+A2Ep4S VXCov6YEskQaNudRcJ9o/tyCuvh0uuTT//OtfS+4MB4g+yTNoFDD+ER412tcXSEHw3AN aYkubO2Tpk7Las5jwV0S/oDPEqOYzh9kouD1L+8NHVaPe/iWrjpaFc1aN6IEiynQOGMD KvZXiSQch2FBpt8U3Pax3SSZaFAhVD03NEfYRI+R/7KXP0l4hFV+ltl06j+dl8cuj63W GOFg== X-Gm-Message-State: ACgBeo1XeryisFNKJFEQYoHLOinI9pCqEIJu/oh+gHI+RWy7Fsc0f/C1 0jrliC+332X0yYWh7yXVYhqF12gvmuvpIBWu X-Google-Smtp-Source: AA6agR6P4qA6YnqL5eoUIybEZCXuC/IhXZthc284hWvbVugAw68yr9UCNx5ce/rO/Ssf1ltrUVqC3Q== X-Received: by 2002:a63:455:0:b0:434:e57c:d99d with SMTP id 82-20020a630455000000b00434e57cd99dmr14670552pge.433.1662787746021; Fri, 09 Sep 2022 22:29:06 -0700 (PDT) Received: from roots.. ([183.221.93.83]) by smtp.gmail.com with ESMTPSA id y6-20020aa793c6000000b00540d75197e5sm731994pff.47.2022.09.09.22.28.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Sep 2022 22:29:05 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: dmitry.fomichev@wdc.com, Markus Armbruster , Eric Blake , qemu-block@nongnu.org, Stefan Hajnoczi , Kevin Wolf , Fam Zheng , damien.lemoal@opensource.wdc.com, hare@suse.de, Hanna Reitz , Sam Li Subject: [PATCH v9 5/7] config: add check to block layer Date: Sat, 10 Sep 2022 13:27:57 +0800 Message-Id: <20220910052759.27517-6-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220910052759.27517-1-faithilikerun@gmail.com> References: <20220910052759.27517-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::433; envelope-from=faithilikerun@gmail.com; helo=mail-pf1-x433.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Putting zoned/non-zoned BlockDrivers on top of each other is not allowed. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi --- block.c | 14 ++++++++++++++ block/file-posix.c | 14 ++++++++++++++ block/raw-format.c | 1 + include/block/block_int-common.h | 5 +++++ 4 files changed, 34 insertions(+) diff --git a/block.c b/block.c index bc85f46eed..dad2ed3959 100644 --- a/block.c +++ b/block.c @@ -7947,6 +7947,20 @@ void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs, return; } + /* + * Non-zoned block drivers do not follow zoned storage constraints + * (i.e. sequential writes to zones). Refuse mixing zoned and non-zoned + * drivers in a graph. + */ + if (!parent_bs->drv->supports_zoned_children && + child_bs->bl.zoned == BLK_Z_HM) { + error_setg(errp, "Cannot add a %s child to a %s parent", + child_bs->bl.zoned == BLK_Z_HM ? "zoned" : "non-zoned", + parent_bs->drv->supports_zoned_children ? + "support zoned children" : "not support zoned children"); + return; + } + if (!QLIST_EMPTY(&child_bs->parents)) { error_setg(errp, "The node %s already has a parent", child_bs->node_name); diff --git a/block/file-posix.c b/block/file-posix.c index 4edfa25d04..354de22860 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -779,6 +779,20 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, goto fail; } } +#ifdef CONFIG_BLKZONED + /* + * The kernel page chache does not reliably work for writes to SWR zones + * of zoned block device because it can not guarantee the order of writes. + */ + if (strcmp(bs->drv->format_name, "zoned_host_device") == 0) { + if (!(s->open_flags & O_DIRECT)) { + error_setg(errp, "driver=zoned_host_device was specified, but it " + "requires cache.direct=on, which was not specified."); + ret = -EINVAL; + return ret; /* No host kernel page cache */ + } + } +#endif if (S_ISBLK(st.st_mode)) { #ifdef BLKDISCARDZEROES diff --git a/block/raw-format.c b/block/raw-format.c index 6b20bd22ef..9441536819 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -614,6 +614,7 @@ static void raw_child_perm(BlockDriverState *bs, BdrvChild *c, BlockDriver bdrv_raw = { .format_name = "raw", .instance_size = sizeof(BDRVRawState), + .supports_zoned_children = true, .bdrv_probe = &raw_probe, .bdrv_reopen_prepare = &raw_reopen_prepare, .bdrv_reopen_commit = &raw_reopen_commit, diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 078ddd7e67..043aa161a0 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -127,6 +127,11 @@ struct BlockDriver { */ bool is_format; + /* + * Set to true if the BlockDriver supports zoned children. + */ + bool supports_zoned_children; + /* * Drivers not implementing bdrv_parse_filename nor bdrv_open should have * this field set to true, except ones that are defined only by their From patchwork Sat Sep 10 05:27:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12972386 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BC08AECAAD5 for ; Sat, 10 Sep 2022 05:42:01 +0000 (UTC) Received: from localhost ([::1]:58472 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWtFg-00032N-Jc for qemu-devel@archiver.kernel.org; Sat, 10 Sep 2022 01:42:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56222) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWt3P-0002ry-E0; Sat, 10 Sep 2022 01:29:19 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]:50792) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oWt3L-0004p5-8m; Sat, 10 Sep 2022 01:29:18 -0400 Received: by mail-pj1-x1036.google.com with SMTP id fv3so3306224pjb.0; Fri, 09 Sep 2022 22:29:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=nseF1HARD/BHEnc5k15AO6TKpiXJzSB/e67hacR5BRw=; b=pf3NL9PhNbwVBKELgxFVBZ4m+Rj2/n+WPYJ0MJiIAk9ove8mOdwryENlgD1tqY8YLN DnWiKEb3pRV84uiUKH53ItbseLO1eJ/QeuyYRy1vktkn8ejW27BLhpc5zGTY5zeXDtwv 6+gZ+yo5V0KjjOxJKlzIBcHddqrREm3wF8wqEJ+4d6MC3FFjViAY0bnygf11lV/YPVr3 btYpgvcHOhSO1iX1pDkzbEecwt07d+8ogmzEHjgolG6Q+ayBCwl6D71I5LYsPgkpRK3Q oMYwTMy4n58CFO15HzaQ16zOUHXnjDXVPtkyF23yQxCuxw56b6XQaW/1dLdTKBiSQGus QD9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=nseF1HARD/BHEnc5k15AO6TKpiXJzSB/e67hacR5BRw=; b=Cu044P2uy5HFfqshYAB7H5yGa9BdT7Cs8CtVQwhr4JXasmJIE3j8to2+OtzTVUNQoW 5BcyybEuhXc4wZ/sLOEzpjTq8GFCO/pxEh3GhRKqVa/ZaRA9jVn/jgSq445gGzixyidn t0n0kUAGPm78pFfs/dyLJRzIJ8QwHPojtwBy1Bue3pKIA7sOPQMgB/wCuZEWVM/EKJFa 4SJupxfFQGI6zwpoQNRKCQRdBWuyUoTvigqYeEKoFIfhqsERjjUrd8oN6G3M8ehYM5NX bJe5x9XmjoGKeDpSVsp7egxLaHO/RYsJcEBDZa1He+ME3RIwR6er1gWJ7P5dAxJf+Wnd lRsw== X-Gm-Message-State: ACgBeo2B9bOSq4tj0cYsZ0Qw/E7ENhVF4ltn8ZncRpafULvl61GhwfAD gLl8Q+Cjgwmu2Pki/TEnfWf3nOOk2XfBzdlI X-Google-Smtp-Source: AA6agR4mLin3tFEbyW39VYEEO8ylF4RHh8kOFGeI24dk2AcqpFbFOsHfZI4kz9G0f9/lLLROnYxbsg== X-Received: by 2002:a17:90a:b00f:b0:1f7:67c6:5df5 with SMTP id x15-20020a17090ab00f00b001f767c65df5mr12870377pjq.59.1662787753400; Fri, 09 Sep 2022 22:29:13 -0700 (PDT) Received: from roots.. ([183.221.93.83]) by smtp.gmail.com with ESMTPSA id y6-20020aa793c6000000b00540d75197e5sm731994pff.47.2022.09.09.22.29.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Sep 2022 22:29:13 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: dmitry.fomichev@wdc.com, Markus Armbruster , Eric Blake , qemu-block@nongnu.org, Stefan Hajnoczi , Kevin Wolf , Fam Zheng , damien.lemoal@opensource.wdc.com, hare@suse.de, Hanna Reitz , Sam Li Subject: [PATCH v9 6/7] qemu-iotests: test new zone operations Date: Sat, 10 Sep 2022 13:27:58 +0800 Message-Id: <20220910052759.27517-7-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220910052759.27517-1-faithilikerun@gmail.com> References: <20220910052759.27517-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=faithilikerun@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We have added new block layer APIs of zoned block devices. Test it with: Create a null_blk device, run each zone operation on it and see whether reporting right zone information. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi --- tests/qemu-iotests/tests/zoned.out | 53 +++++++++++++++++++ tests/qemu-iotests/tests/zoned.sh | 85 ++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 tests/qemu-iotests/tests/zoned.out create mode 100755 tests/qemu-iotests/tests/zoned.sh diff --git a/tests/qemu-iotests/tests/zoned.out b/tests/qemu-iotests/tests/zoned.out new file mode 100644 index 0000000000..0c8f96deb9 --- /dev/null +++ b/tests/qemu-iotests/tests/zoned.out @@ -0,0 +1,53 @@ +QA output created by zoned.sh +Testing a null_blk device: +Simple cases: if the operations work +(1) report the first zone: +start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2] + +report the first 10 zones +start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2] +start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80000, zcond:1, [type: 2] +start: 0x100000, len 0x80000, cap 0x80000, wptr 0x100000, zcond:1, [type: 2] +start: 0x180000, len 0x80000, cap 0x80000, wptr 0x180000, zcond:1, [type: 2] +start: 0x200000, len 0x80000, cap 0x80000, wptr 0x200000, zcond:1, [type: 2] +start: 0x280000, len 0x80000, cap 0x80000, wptr 0x280000, zcond:1, [type: 2] +start: 0x300000, len 0x80000, cap 0x80000, wptr 0x300000, zcond:1, [type: 2] +start: 0x380000, len 0x80000, cap 0x80000, wptr 0x380000, zcond:1, [type: 2] +start: 0x400000, len 0x80000, cap 0x80000, wptr 0x400000, zcond:1, [type: 2] +start: 0x480000, len 0x80000, cap 0x80000, wptr 0x480000, zcond:1, [type: 2] + +report the last zone: +start: 0x1f380000, len 0x80000, cap 0x80000, wptr 0x1f380000, zcond:1, [type: 2] + + +(2) opening the first zone +report after: +start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:3, [type: 2] + +opening the second zone +report after: +start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80000, zcond:3, [type: 2] + +opening the last zone +report after: +start: 0x1f380000, len 0x80000, cap 0x80000, wptr 0x1f380000, zcond:3, [type: 2] + + +(3) closing the first zone +report after: +start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2] + +closing the last zone +report after: +start: 0x1f380000, len 0x80000, cap 0x80000, wptr 0x1f380000, zcond:1, [type: 2] + + +(4) finishing the second zone +After finishing a zone: +start: 0x80000, len 0x80000, cap 0x80000, wptr 0x100000, zcond:14, [type: 2] + + +(5) resetting the second zone +After resetting a zone: +start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80000, zcond:1, [type: 2] +*** done diff --git a/tests/qemu-iotests/tests/zoned.sh b/tests/qemu-iotests/tests/zoned.sh new file mode 100755 index 0000000000..871f47efed --- /dev/null +++ b/tests/qemu-iotests/tests/zoned.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# +# Test zone management operations. +# + +seq="$(basename $0)" +echo "QA output created by $seq" +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img + sudo rmmod null_blk +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +# This test only runs on Linux hosts with raw image files. +_supported_fmt raw +_supported_proto file +_supported_os Linux + +QEMU_IO="build/qemu-io" +IMG="--image-opts -n driver=zoned_host_device,filename=/dev/nullb0" +QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT + +echo "Testing a null_blk device:" +echo "Simple cases: if the operations work" +sudo modprobe null_blk nr_devices=1 zoned=1 + +echo "(1) report the first zone:" +sudo $QEMU_IO $IMG -c "zrp 0 1" +echo +echo "report the first 10 zones" +sudo $QEMU_IO $IMG -c "zrp 0 10" +echo +echo "report the last zone:" +sudo $QEMU_IO $IMG -c "zrp 0x3e70000000 2" # 0x3e70000000 / 512 = 0x1f380000 +echo +echo +echo "(2) opening the first zone" +sudo $QEMU_IO $IMG -c "zo 0 268435456" # 268435456 / 512 = 524288 +echo "report after:" +sudo $QEMU_IO $IMG -c "zrp 0 1" +echo +echo "opening the second zone" +sudo $QEMU_IO $IMG -c "zo 268435456 268435456" # +echo "report after:" +sudo $QEMU_IO $IMG -c "zrp 268435456 1" +echo +echo "opening the last zone" +sudo $QEMU_IO $IMG -c "zo 0x3e70000000 268435456" +echo "report after:" +sudo $QEMU_IO $IMG -c "zrp 0x3e70000000 2" +echo +echo +echo "(3) closing the first zone" +sudo $QEMU_IO $IMG -c "zc 0 268435456" +echo "report after:" +sudo $QEMU_IO $IMG -c "zrp 0 1" +echo +echo "closing the last zone" +sudo $QEMU_IO $IMG -c "zc 0x3e70000000 268435456" +echo "report after:" +sudo $QEMU_IO $IMG -c "zrp 0x3e70000000 2" +echo +echo +echo "(4) finishing the second zone" +sudo $QEMU_IO $IMG -c "zf 268435456 268435456" +echo "After finishing a zone:" +sudo $QEMU_IO $IMG -c "zrp 268435456 1" +echo +echo +echo "(5) resetting the second zone" +sudo $QEMU_IO $IMG -c "zrs 268435456 268435456" +echo "After resetting a zone:" +sudo $QEMU_IO $IMG -c "zrp 268435456 1" +# success, all done +echo "*** done" +rm -f $seq.full +status=0 From patchwork Sat Sep 10 05:27:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12972385 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 129E6ECAAD5 for ; Sat, 10 Sep 2022 05:33:35 +0000 (UTC) Received: from localhost ([::1]:39018 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oWt7X-0006Fa-0K for qemu-devel@archiver.kernel.org; Sat, 10 Sep 2022 01:33:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56224) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oWt3V-0002xu-4o; Sat, 10 Sep 2022 01:29:25 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]:34342) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oWt3T-0004qS-0m; Sat, 10 Sep 2022 01:29:24 -0400 Received: by mail-pl1-x62a.google.com with SMTP id f24so3649920plr.1; Fri, 09 Sep 2022 22:29:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=BFPxl3nAGF1rBBCyjnFCSTHHYUfwTOepHasYOlesocs=; b=TxqlioPqylUedUAcHybaQxUM1WTbi3l7GuJJasambQ8FcEB/UfA6PKG0Ey8okeIVhA DqkAtcsmf12dQhDLtPCjd739Bu9fvQBLMWiMbSRSWEY3Vyr+5EJluFGCQDnFhxT/8JqO 3GA5w2LUznXYRbKNhHulT6UP8t+inaesdK+xmg8GuMsUxrQb5zDMn6se2MsJ/DuXcHir wS2DZQmRJ93swu/z7mzUMa1XoZp0wlqY8BmyB+rZWjYAnYA/ZGuaPX5Q4nOL7xA9AC76 rzI6F0PK1HAKREL3l5QpM/iKS2RzpwNHkyvsIP5kPJVKezSrPf8Xy4hZfKYjEpw7whZ0 LGfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=BFPxl3nAGF1rBBCyjnFCSTHHYUfwTOepHasYOlesocs=; b=J2pwzQlYIlEgPVQbTD83TC9I/jfZF1IUfkLsZ/z5EGFVIAHSHdpW2pSMlWaleOg+fm 74H4JMpHoulBZzD/bSpdTErqPqBegdl4O/HbI6aOzsXKkGIwV1k09upZgF8NvU2oWlcj Qkgv7kR2J2qCUMA0hW5uQyiwui4DF4LB0Fyqn6BS5UAS4ykIByxZiyg67UZTwlEhI03G yoQdAt9PIWguPie0qxnJrWN0d5K72K8ahKirdXCokxAvwSqG7qxSRtgm1hPUhHDbemIU 4KNwo2700tNbX5WpXTmWtSfk6TIzyq6PN9YJHQc8aBRlGtsviCpq8GmaSuq/oC9Km9Ja 6MyQ== X-Gm-Message-State: ACgBeo0QtHlRAEcnERwJEo9S3DvObZcDWygtEvpumTMUVFiR8CcJuEH7 QRr7BEcnDrfTrqvz1Oy3sZUPoWticaqaw1Cj X-Google-Smtp-Source: AA6agR7iNHjln9Jjq5onrNpIBRerig6eOu0gS6cr34m73X4Zl0mR5Ph2XOFicXD1F550rXRG9PWD+A== X-Received: by 2002:a17:902:f545:b0:178:12e5:9efa with SMTP id h5-20020a170902f54500b0017812e59efamr3875736plf.100.1662787760682; Fri, 09 Sep 2022 22:29:20 -0700 (PDT) Received: from roots.. ([183.221.93.83]) by smtp.gmail.com with ESMTPSA id y6-20020aa793c6000000b00540d75197e5sm731994pff.47.2022.09.09.22.29.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Sep 2022 22:29:20 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: dmitry.fomichev@wdc.com, Markus Armbruster , Eric Blake , qemu-block@nongnu.org, Stefan Hajnoczi , Kevin Wolf , Fam Zheng , damien.lemoal@opensource.wdc.com, hare@suse.de, Hanna Reitz , Sam Li Subject: [PATCH v9 7/7] docs/zoned-storage: add zoned device documentation Date: Sat, 10 Sep 2022 13:27:59 +0800 Message-Id: <20220910052759.27517-8-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220910052759.27517-1-faithilikerun@gmail.com> References: <20220910052759.27517-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=faithilikerun@gmail.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Add the documentation about the zoned device support to virtio-blk emulation. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi --- docs/devel/zoned-storage.rst | 41 ++++++++++++++++++++++++++ docs/system/qemu-block-drivers.rst.inc | 6 ++++ 2 files changed, 47 insertions(+) create mode 100644 docs/devel/zoned-storage.rst diff --git a/docs/devel/zoned-storage.rst b/docs/devel/zoned-storage.rst new file mode 100644 index 0000000000..ead2d149cc --- /dev/null +++ b/docs/devel/zoned-storage.rst @@ -0,0 +1,41 @@ +============= +zoned-storage +============= + +Zoned Block Devices (ZBDs) devide the LBA space into block regions called zones +that are larger than the LBA size. It can only allow sequential writes, which +reduces write amplification in SSDs, leading to higher throughput and increased +capacity. More details about ZBDs can be found at: + +https://zonedstorage.io/docs/introduction/zoned-storage + +1. Block layer APIs for zoned storage +------------------------------------- +QEMU block layer has three zoned storage model: +- BLK_Z_HM: This model only allows sequential writes access. It supports a set +of ZBD-specific I/O request that used by the host to manage device zones. +- BLK_Z_HA: It deals with both sequential writes and random writes access. +- BLK_Z_NONE: Regular block devices and drive-managed ZBDs are treated as +non-zoned devices. + +The block device information resides inside BlockDriverState. QEMU uses +BlockLimits struct(BlockDriverState::bl) that is continuously accessed by the +block layer while processing I/O requests. A BlockBackend has a root pointer to +a BlockDriverState graph(for example, raw format on top of file-posix). The +zoned storage information can be propagated from the leaf BlockDriverState all +the way up to the BlockBackend. If the zoned storage model in file-posix is +set to BLK_Z_HM, then block drivers will declare support for zoned host device. + +The block layer APIs support commands needed for zoned storage devices, +including report zones, four zone operations, and zone append. + +2. Emulating zoned storage controllers +-------------------------------------- +When the BlockBackend's BlockLimits model reports a zoned storage device, users +like the virtio-blk emulation or the qemu-io-cmds.c utility can use block layer +APIs for zoned storage emulation or testing. + +For example, the command line for zone report testing a null_blk device of +qemu-io-cmds.c is: +$ path/to/qemu-io --image-opts driver=zoned_host_device,filename=/dev/nullb0 -c +"zrp offset nr_zones" diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc index dfe5d2293d..0b97227fd9 100644 --- a/docs/system/qemu-block-drivers.rst.inc +++ b/docs/system/qemu-block-drivers.rst.inc @@ -430,6 +430,12 @@ Hard disks you may corrupt your host data (use the ``-snapshot`` command line option or modify the device permissions accordingly). +Zoned block devices + Zoned block devices can be passed through to the guest if the emulated storage + controller supports zoned storage. Use ``--blockdev zoned_host_device, + node-name=drive0,filename=/dev/nullb0`` to pass through ``/dev/nullb0`` + as ``drive0``. + Windows ^^^^^^^