From patchwork Thu Sep 29 08:36:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12993705 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 7F858C04A95 for ; Thu, 29 Sep 2022 08:53:50 +0000 (UTC) Received: from localhost ([::1]:50746 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1odpIj-0008Nq-F8 for qemu-devel@archiver.kernel.org; Thu, 29 Sep 2022 04:53:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36086) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1odp2R-0000Nw-7H; Thu, 29 Sep 2022 04:37:00 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]:40515) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1odp2P-0007hU-LJ; Thu, 29 Sep 2022 04:36:58 -0400 Received: by mail-pj1-x1036.google.com with SMTP id h8-20020a17090a054800b00205ccbae31eso5256633pjf.5; Thu, 29 Sep 2022 01:36:56 -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=nPZc0MXnc/sM9pOAqbXMOSO2S58RbTw5gtX0VW17ltqag5qkYtEh6zaT7V4OEO2GMc FXWdPLamqs9ZRQko8tgX5suOlAJe29iZxzlK2/gfEUsWXpDNsDzwpnJODxpRCIVEKHBW wtbCpQ4/iMWjEFZhdF0hL9S0vexyRGndvFpYQsq/Oj6iLZ4DJtfPl5MQXt9esA4hUHLq Xhh2dAM/Xcb7SRBg6aNs8a2Ou10J5SsYit4blZysmgeBZVJuh+mywHgyGuEQzTt5cqvu VoalZWZ+wXnT6Yya2/aamnqgjVNJU47Mbf0Ez4Z9aD9MV3PMTl/Ttd5+nfN+Mzgb4uLo We0Q== 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=pgTk9bU1pudAzz0eirsGFoBUtP4R7Sg7gGVWDrjOO4Qo+IxkbiVK4uk/TpfhvELyOP 9O2esx3AqqaPwiz9TZLXfAOh/PHqNLS0slHj8MHbL72HIHprqr8rfk2yaXFQOwoG+OmW mfGsx+KUU/skcsxh2ljUlioGiBDXCPOOLp8F8ZbE+GSYJvcEsXs7r7qkHnGLj6XuJPLt tEv7ggQId4zfZ+9/yZByxzg79mdBBmIcnQwKGC7Yp1TvWnpNgx/st7OIBFKJPW068dgH P23ijYWHUBFYSSnvNMXxtcNcpDKxl8KzyJ5gLKD3sNodOsHI9NL1WEuCj8UqRgNuoqvi /TxA== X-Gm-Message-State: ACrzQf2r1XWP94ja4UIc7baX3sKt1zf2JbsqZdjMqDSS1rtSvJtmXg+Y VwxHB6dksMCrknGBdsH3X6ot7PI/mQUWFQ== X-Google-Smtp-Source: AMsMyM5oek9xYhu43NRoFFT+ItirRIJUOHRnpOmNEfEEkw2Y7utC7xLq7RCPoqfZsfoa/kG8y0/uyg== X-Received: by 2002:a17:902:7294:b0:178:a2be:ac13 with SMTP id d20-20020a170902729400b00178a2beac13mr2293309pll.59.1664440615523; Thu, 29 Sep 2022 01:36:55 -0700 (PDT) Received: from roots.. ([112.44.202.63]) by smtp.gmail.com with ESMTPSA id s5-20020a170902ea0500b0017829a3df46sm5324233plg.204.2022.09.29.01.36.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 01:36:55 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: damien.lemoal@opensource.wdc.com, Kevin Wolf , hare@suse.de, Hanna Reitz , Markus Armbruster , Fam Zheng , stefanha@redhat.com, Eric Blake , qemu-block@nongnu.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v10 1/7] include: add zoned device structs Date: Thu, 29 Sep 2022 16:36:25 +0800 Message-Id: <20220929083631.61899-2-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220929083631.61899-1-faithilikerun@gmail.com> References: <20220929083631.61899-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 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 Thu Sep 29 08:36:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12993704 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 966ECC04A95 for ; Thu, 29 Sep 2022 08:53:42 +0000 (UTC) Received: from localhost ([::1]:37652 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1odpIb-0007xA-8a for qemu-devel@archiver.kernel.org; Thu, 29 Sep 2022 04:53:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33768) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1odp2a-0000Sd-QT; Thu, 29 Sep 2022 04:37:10 -0400 Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]:33382) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1odp2Y-0007jF-Be; Thu, 29 Sep 2022 04:37:07 -0400 Received: by mail-pg1-x533.google.com with SMTP id f193so877269pgc.0; Thu, 29 Sep 2022 01:37:05 -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=+JQ66bLElXnn3EMf7/PaRKI9w4ydiSjIGiaM8hZtrgM=; b=RpfE0+E7C6vEM4YCXB3kX65FrEN1FdLNyDUuOYW3yLEWuwYqyKBncItYM8ZS5hBYVz HBRr5oNAQMbYq67K/P7V7HYjIawhg506FUERPf98u6/Y/kqIT6R5NZk/YpdkPwr9ZTwt iAh8Zf9quqBNRCAFxh+O4+9YBCH4bJjDenM+rQKuDD4nv3ktyt0pFp9Rzl59yMMRdqgP q6NKZhtP5mESR1GFidUKFT2pihr5qJufeET39HaTI27T5u1/JBI4Mw6LXK2KIkaJk9e4 hCzxI+Q4XI14Xh5ozGQHxMFkVxtHd0X34c+xApEYMqeVhS+0nJl9NHU6SKFR/cRwchh7 CW3w== 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=+JQ66bLElXnn3EMf7/PaRKI9w4ydiSjIGiaM8hZtrgM=; b=PNPDBlnwX0mOnp/aVcYz5Qk2acrw5pZfnFiCsTIO1/3TbOgNnYNEAmXxn/tUqr8sC4 +lGTeYZi8Zo55/K/L3COkFMAt5lxKz31Cvh47riBRUZmRBxdHCTjpIhAUZBCRl5h8qic dhX5KTMNKN9E2+PZZt48Yhr4L4Y3xN9/tSxhuGwkeffuDkQWw7q4jT3n9jhPkaKkHdg9 gm7PAQMqsS7tOXDSKhqFchzmGd/cqYzqOXFn36W3tt/6951mhxGlkwGBxvAL7tIevrLM b0rwa7FYXFmxbgiOoCAzsJivOT94R2YmYzKEghAkoEH+p4ujLo3VDVmQodxV4IEjYkqW Ni4Q== X-Gm-Message-State: ACrzQf35Nc5yZQjaM3qAQiR/h+pEUJBHb9Ougxf9uEj2irX71UiPlyrH 44cRzzklY5vnhqgxxylpVjnGbByV1NMf6g== X-Google-Smtp-Source: AMsMyM4VMm9j3CejHcFoUXBkhsPkiCzGDVIkFoDGIXMDrQCPvhFZ+FdcCnqOgt9Yorz62B38Kn17bw== X-Received: by 2002:a63:4384:0:b0:43a:18ce:f98a with SMTP id q126-20020a634384000000b0043a18cef98amr1899391pga.273.1664440624280; Thu, 29 Sep 2022 01:37:04 -0700 (PDT) Received: from roots.. ([112.44.202.63]) by smtp.gmail.com with ESMTPSA id s5-20020a170902ea0500b0017829a3df46sm5324233plg.204.2022.09.29.01.36.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 01:37:03 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: damien.lemoal@opensource.wdc.com, Kevin Wolf , hare@suse.de, Hanna Reitz , Markus Armbruster , Fam Zheng , stefanha@redhat.com, Eric Blake , qemu-block@nongnu.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v10 2/7] file-posix: introduce helper functions for sysfs attributes Date: Thu, 29 Sep 2022 16:36:26 +0800 Message-Id: <20220929083631.61899-3-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220929083631.61899-1-faithilikerun@gmail.com> References: <20220929083631.61899-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x533.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 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 Thu Sep 29 08:36:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12993718 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 52E77C6FA82 for ; Thu, 29 Sep 2022 08:59:01 +0000 (UTC) Received: from localhost ([::1]:53352 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1odpNk-0004sQ-Be for qemu-devel@archiver.kernel.org; Thu, 29 Sep 2022 04:59:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52152) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1odp2m-0000h8-GY; Thu, 29 Sep 2022 04:37:25 -0400 Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]:38883) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1odp2g-0007ja-Ts; Thu, 29 Sep 2022 04:37:20 -0400 Received: by mail-pg1-x533.google.com with SMTP id 129so847134pgc.5; Thu, 29 Sep 2022 01:37: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=H9FlPjialttbgWBGdyUs6RB7k1ork6IUjXSWOE3vzCI=; b=f1v6CA9B8Nk1S7HK9ZBXBYfR85Lggy8oWf2qDDPPZJrf4pg0w3Acn33aUGRsh4H0mi o1K+ikQFR9ZTL717/eE2rASFqmJae6BFvNwjzaWxnko52u0IziUUgG1lvByTcwS4xwuT bFOIaLiGmzFZqyFWdd8eFJPXqNw3ve0XJoKyTPS/RVtz6+sNcs+peNYapsuESWhh8LH4 QLp8H5kKP0O+dN4ZHvDnbogNpGAk10h5AdS7oEvApmWgabZfbN7JQZWNNalWULvwwyy6 JYU/NyBTtSq57bn3LNzKWech4hWRKYMoGKHeTZq7B7OY9JfOPWraMlP51hU74UAWE9Wf 83mg== 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=H9FlPjialttbgWBGdyUs6RB7k1ork6IUjXSWOE3vzCI=; b=4sbxmT3pv21IvJHZ0B2cJTJ7X4qs3ztYrDmAl8pm1Ppgru2t2l3O8K5PKFWwV4sHgi y6cJldjPL4SXYOUfrpRYg6XAAh2SB6vxlCadpEnclQtI9VZ7SzKOkNlAYXga9Qj6E+N+ z7yopvUM4F5mY1b9JE8l0nX8WL2XQh+ciR/Lcq8amd46MTA3gQnqg3xdSuPiTxl8kT7u kNUOsHOvg3fiRjnMtjnVNxLpX3FVrifGDb0vAFFEADOOL5jNwoC5Hjg2PcUz/jjz6d9e yCGGL0oJHtYC75AfFceA0Cl+qHPdONxXHpJSdm9AcgFEqg+IOdlkl/dAp/W/utvm84QM n/BA== X-Gm-Message-State: ACrzQf30foypQOVNzWW5Xc+KamOzce2fAoyYgzbHqZkE7h3+R5weXBEW xPxvV3Mug34+GzU95/h8z1QbFnyL+V8odQ== X-Google-Smtp-Source: AMsMyM5vddStyqVsig5G58ayamutEZTXpLHn/Ee6GfDarahWnv+9fx3Sa7RvNywuX3V5XbD7J2ZQKg== X-Received: by 2002:a63:4918:0:b0:439:1802:dda3 with SMTP id w24-20020a634918000000b004391802dda3mr1880484pga.467.1664440632856; Thu, 29 Sep 2022 01:37:12 -0700 (PDT) Received: from roots.. ([112.44.202.63]) by smtp.gmail.com with ESMTPSA id s5-20020a170902ea0500b0017829a3df46sm5324233plg.204.2022.09.29.01.37.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 01:37:12 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: damien.lemoal@opensource.wdc.com, Kevin Wolf , hare@suse.de, Hanna Reitz , Markus Armbruster , Fam Zheng , stefanha@redhat.com, Eric Blake , qemu-block@nongnu.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v10 3/7] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls Date: Thu, 29 Sep 2022 16:36:27 +0800 Message-Id: <20220929083631.61899-4-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220929083631.61899-1-faithilikerun@gmail.com> References: <20220929083631.61899-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x533.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 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 | 146 +++++++++++++ block/file-posix.c | 340 +++++++++++++++++++++++++++++- block/io.c | 41 ++++ include/block/block-common.h | 4 + include/block/block-io.h | 7 + include/block/block_int-common.h | 24 +++ include/block/raw-aio.h | 6 +- include/sysemu/block-backend-io.h | 17 ++ meson.build | 4 + qapi/block-core.json | 8 +- qemu-io-cmds.c | 148 +++++++++++++ 11 files changed, 741 insertions(+), 4 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index d4a5df2ac2..f7f7acd6f4 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,143 @@ 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 device zone 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) { + blk_dec_in_flight(blk); + 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..0a6c781201 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,41 @@ 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) { + error_report("Invalid zone size %" PRId32 " sectors ", ret); + bs->bl.zoned = BLK_Z_NONE; + return; + } + bs->bl.zone_size = ret * 512; + + 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; + } + + ret = get_sysfs_long_val(&st, "nr_zones"); + if (ret >= 0) { + bs->bl.nr_zones = ret; + } + + ret = ioctl(s->fd, BLKGETSIZE64, &bs->bl.capacity); + if (ret != 0) { + error_report("Invalid device capacity %" PRId64 " bytes ", bs->bl.capacity); + return; + } + } } static int check_for_dasd(int fd) @@ -1850,6 +1897,147 @@ 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, + const struct blk_zone_report *rep) { + zone->start = blkz->start << BDRV_SECTOR_BITS; + zone->length = blkz->len << BDRV_SECTOR_BITS; + zone->wp = blkz->wp << BDRV_SECTOR_BITS; + + if (rep->flags & BLK_ZONE_REP_CAPACITY) { + zone->cap = blkz->capacity << BDRV_SECTOR_BITS; + } else { + zone->cap = blkz->len << BDRV_SECTOR_BITS; + } + + 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 + +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; + + struct blk_zone *blkz; + int64_t rep_size; + unsigned int nrz; + int ret, n = 0, i = 0; + + nrz = *nr_zones; + 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], rep); + /* The next report should start after the last zone reported */ + sector = blkz[i].start + blkz[i].len; + } + } + + *nr_zones = n; + 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 +3210,105 @@ 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_size, zone_size_mask; + const char *zone_op_name; + unsigned long zone_op; + bool is_all = false; + + zone_size = bs->bl.zone_size; + zone_size_mask = zone_size - 1; + if (offset & zone_size_mask) { + error_report("sector offset %" PRId64 " is not aligned to zone size " + "%" PRId64 "", offset / 512, zone_size / 512); + return -EINVAL; + } + + if (((offset + len) < bs->bl.capacity && len & zone_size_mask) || + offset + len > bs->bl.capacity) { + error_report("number of sectors %" PRId64 " is not aligned to zone size" + " %" PRId64 "", len / 512, zone_size / 512); + 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 +4039,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 +4347,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..5ab2d169c8 100644 --- a/block/io.c +++ b/block/io.c @@ -3198,6 +3198,47 @@ out: return co.ret; } +int coroutine_fn 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 coroutine_fn 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-common.h b/include/block/block-common.h index 36bd0e480e..8efb6b0c43 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -49,6 +49,10 @@ typedef struct BlockDriver BlockDriver; typedef struct BdrvChild BdrvChild; typedef struct BdrvChildClass BdrvChildClass; +#ifndef HAVE_BLK_ZONE_REP_CAPACITY +#define BLK_ZONE_REP_CAPACITY (1 << 0) +#endif + typedef enum BlockZoneOp { BLK_ZO_OPEN, BLK_ZO_CLOSE, 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..cdc06e77a6 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,24 @@ typedef struct BlockLimits { /* device zone model */ BlockZoneModel zoned; + + /* zone size expressed in bytes */ + uint32_t zone_size; + + /* 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; + + /* device capacity expressed in bytes */ + int64_t capacity; } 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 63cfb844cf..9a797388ad 100644 --- a/meson.build +++ b/meson.build @@ -1882,6 +1882,7 @@ config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed()) # 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')) @@ -1975,6 +1976,9 @@ config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', cc.has_member('struct stat', 'st_atim', prefix: '#include ')) +config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY', + cc.has_member('struct blk_zone', 'capacity', + prefix: '#include ')) # has_type config_host_data.set('CONFIG_IOVEC', diff --git a/qapi/block-core.json b/qapi/block-core.json index f21fa235f2..ee87c1df8a 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..e56c8d1c30 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1712,6 +1712,149 @@ static const cmdinfo_t flush_cmd = { .oneline = "flush all in-core file state to disk", }; +static inline int64_t tosector(int64_t bytes) { + return bytes >> BDRV_SECTOR_BITS; +} + +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", + tosector(zones[i].start), tosector(zones[i].length), + tosector(zones[i].cap), tosector(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 +2647,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 Thu Sep 29 08:36:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12993766 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 4F9A7C07E9D for ; Thu, 29 Sep 2022 09:14:14 +0000 (UTC) Received: from localhost ([::1]:53958 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1odpcT-0007Wj-96 for qemu-devel@archiver.kernel.org; Thu, 29 Sep 2022 05:14:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52642) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1odp2r-0000hr-Pj; Thu, 29 Sep 2022 04:37:25 -0400 Received: from mail-pl1-x636.google.com ([2607:f8b0:4864:20::636]:34603) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1odp2q-0007kq-74; Thu, 29 Sep 2022 04:37:25 -0400 Received: by mail-pl1-x636.google.com with SMTP id n7so687624plp.1; Thu, 29 Sep 2022 01:37: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=57QnA/2Ol0DHKqe6YXTY3Gnm3ly91wDIHKEkFzHSeHU=; b=nnBX+pNBJXHXztOORjZ9jTZrBKRjeo3mF2vvl4Gv/87bw9ymnAuoFH7dUEjEevhoCC H4RCF9/8LlVrwfMhEqb+0vfH2UadLV/Rpi6X0uI8wDSeNoocXMV/q1D4hzv2e/SW9R+/ 9l68HMUn2XIBDP2RTS9G94LC4g2kxeG5+TKrZT6yG1aQD+ijn6ypWnK9IwL+SmvcIuhH nZn6XSjhCgWgbnWH86mcZfQkIe9GXTmQCsSYr3VGFLeiKomRM4Gu+k9836CWboO1uU8u V9rBiLBAl7VnoI1iBA6GtSOClWQN9PL4C327zUOyuia5jJWK17fVchNwqWSyQu/u7s8Y KGbg== 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=57QnA/2Ol0DHKqe6YXTY3Gnm3ly91wDIHKEkFzHSeHU=; b=dsLcfT6++THTAAXzrUQimBZYZ6Ubx2APhyY9f7mxVTXRgz3y6fUtT8MKgtc0laUh+3 bbgHp2IoGtAHccZARVX1SutD0ZthQnmHrZVsc9KDW0KMQuF+nRd4+L9TxMLU1laXr9mu 8F2i+K1nxGINurJWD2/sfzU5enB5inU8qshBGgxHZjG/FOPqGjgEIdmdhZZ+lmzhZKdr NTMbJkIUZK1jHFVXp94uxcKm7B/f+JHBhGRgidJBzAXRXgcudfHPPYy28UmfrpEBmO5x i+0kK+rKJSyOg3m8BF65Nglcw6L10Wo3XD54s2t+dmnol+TqOmFpOwAH8FVUDZux5j/O sa5w== X-Gm-Message-State: ACrzQf0GzFHSjNgo5ABvDYhKokjuYNLt6sr/UHNkwF+awr9o+qpjBiFQ jsTglUH2L3RsD0hJc308IQjiUQ8ODMRHbA== X-Google-Smtp-Source: AMsMyM5bGU5nurdXPoY6b+eyYBtEKfmEOEDPSiug/iNMRUcKNUbk8/I5w89EWC/x0n4EjwBgc1ZTJw== X-Received: by 2002:a17:90b:164b:b0:202:d347:2512 with SMTP id il11-20020a17090b164b00b00202d3472512mr2511282pjb.185.1664440640615; Thu, 29 Sep 2022 01:37:20 -0700 (PDT) Received: from roots.. ([112.44.202.63]) by smtp.gmail.com with ESMTPSA id s5-20020a170902ea0500b0017829a3df46sm5324233plg.204.2022.09.29.01.37.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 01:37:20 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: damien.lemoal@opensource.wdc.com, Kevin Wolf , hare@suse.de, Hanna Reitz , Markus Armbruster , Fam Zheng , stefanha@redhat.com, Eric Blake , qemu-block@nongnu.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v10 4/7] raw-format: add zone operations to pass through requests Date: Thu, 29 Sep 2022 16:36:28 +0800 Message-Id: <20220929083631.61899-5-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220929083631.61899-1-faithilikerun@gmail.com> References: <20220929083631.61899-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::636; envelope-from=faithilikerun@gmail.com; helo=mail-pl1-x636.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 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 Thu Sep 29 08:36:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12993780 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 A686BC433F5 for ; Thu, 29 Sep 2022 09:18:49 +0000 (UTC) Received: from localhost ([::1]:36580 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1odpgu-0000qf-LX for qemu-devel@archiver.kernel.org; Thu, 29 Sep 2022 05:18:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49830) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1odp33-0000ka-Fb; Thu, 29 Sep 2022 04:38:05 -0400 Received: from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f]:45003) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1odp2w-0007lL-HK; Thu, 29 Sep 2022 04:37:37 -0400 Received: by mail-pg1-x52f.google.com with SMTP id c7so827192pgt.11; Thu, 29 Sep 2022 01:37:29 -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=P5s1r+TdljxsgJm9EoSaBP3Yzp8UWe8irO8JsQPp+oo=; b=qfJAqeI1lnC4OJhQSDPnJFnzmHxTRc5GCTYVoWJ1kCvUFeWt1eSNbGzgAaGVhR5IoP 0omRhPmkWoo/TlviPs8L67uOmQlvSPgn3rrfKYWGRi6CJhpu1SLY+Q/ItznBOopoCBcr 4BRbwqupGjMnrZxREbOfJaQDCRG6yVJcZKXFgGEw/cVSXN6VeBmQg5WpRMILXES8CRQt KZ7FQ86D4ckNLqsTBRq7b2gX3OMD84uWA9qrf4U4hbU4GpO//3luQcdKRAYRnUah+CDB gNmuJh75GdRosn25bXMRyfxb2GsNWsXbxHJBrLt7zBAT+Yc9gyk1blEq7L4h/a9WBrOP YLiA== 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=P5s1r+TdljxsgJm9EoSaBP3Yzp8UWe8irO8JsQPp+oo=; b=k8iR+DqKOuMKImIW7m5pP+Ds9WNhT98HyN61m9x1VukcaN28mR+PTbCl6b5vnV/BAF 3R4rk+52sE8dAW2QMta4VFNy/fmtR1FNZ2thdyx50SPPnT++Miwxa0hXYSOEiciu/oUy cOLDtN7H7tMl21LZeyzeUElNcqrPjDezpSVcod3QN2wV+/IrbqlSX6QM+L2ix5JuAriN eHZxvVbEY/rJszWUPOiHo3SW5AVlj6ioVriQRBLA4YRTGFf0KBWImjbsXE8NsraRWXSV aTPqKSjR9zs1Xreu9tIJtrRKPw5UEjgNPYFtGLcXcGPuRX0QsnsnRiHKOMdP95YH5BUQ 4gSQ== X-Gm-Message-State: ACrzQf2UMQ3B6azWi+/l0RDJ916ErIvgtFyZVBkL2GZK9tuoG+1ulxkF 0iXm9BUV5RK0sbrmWLPuGgdGCGXtcag6WA== X-Google-Smtp-Source: AMsMyM64n2ldw/7y5Dm//u+CfsWhedgtvRYe5j+ugkEnzz6lgWfx2hDNgk6YGTJRFHR8EsVBrwm64w== X-Received: by 2002:a05:6a00:17a1:b0:542:be09:7b23 with SMTP id s33-20020a056a0017a100b00542be097b23mr2347622pfg.12.1664440648377; Thu, 29 Sep 2022 01:37:28 -0700 (PDT) Received: from roots.. ([112.44.202.63]) by smtp.gmail.com with ESMTPSA id s5-20020a170902ea0500b0017829a3df46sm5324233plg.204.2022.09.29.01.37.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 01:37:28 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: damien.lemoal@opensource.wdc.com, Kevin Wolf , hare@suse.de, Hanna Reitz , Markus Armbruster , Fam Zheng , stefanha@redhat.com, Eric Blake , qemu-block@nongnu.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v10 5/7] config: add check to block layer Date: Thu, 29 Sep 2022 16:36:29 +0800 Message-Id: <20220929083631.61899-6-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220929083631.61899-1-faithilikerun@gmail.com> References: <20220929083631.61899-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52f; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x52f.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 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 | 17 +++++++++++++++++ block/file-posix.c | 13 +++++++++++++ block/raw-format.c | 1 + include/block/block_int-common.h | 5 +++++ 4 files changed, 36 insertions(+) mode change 100644 => 100755 block.c mode change 100644 => 100755 block/file-posix.c diff --git a/block.c b/block.c old mode 100644 new mode 100755 index bc85f46eed..bf2f2918e7 --- a/block.c +++ b/block.c @@ -7947,6 +7947,23 @@ 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 && + /* The host-aware model allows zoned storage constraints and random + * write. Allow mixing host-aware and non-zoned drivers. Using + * host-aware device as a regular device. */ + 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 old mode 100644 new mode 100755 index 0a6c781201..73656d87f2 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -779,6 +779,19 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, goto fail; } } +#ifdef CONFIG_BLKZONED + /* + * The kernel page cache 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."); + return -EINVAL; /* 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 cdc06e77a6..37dddc603c 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 Thu Sep 29 08:36:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12993733 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 191F9C07E9D for ; Thu, 29 Sep 2022 09:05:01 +0000 (UTC) Received: from localhost ([::1]:47588 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1odpTY-0000oG-4X for qemu-devel@archiver.kernel.org; Thu, 29 Sep 2022 05:05:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49832) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1odp36-0000kg-1C; Thu, 29 Sep 2022 04:38:05 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]:56174) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1odp34-0007lh-97; Thu, 29 Sep 2022 04:37:39 -0400 Received: by mail-pj1-x102b.google.com with SMTP id cv6so676173pjb.5; Thu, 29 Sep 2022 01:37: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=7U200FudwbpHutc22Z/SL8svBLcZPO5nI24IbArJq+8=; b=TB4FxhRLeBEjkLQmUlbDihQ3Ysb2ub7V4XsN5ZZWwzjubrbUYxhcgZUbeHgOM0wpt6 wXefHh7lHbxSvOxnTy0fcCE4AWMehTLxnVKBX5+UCS9MsOSjvyCbfTbeENIJ4TJNcm2X YoNegNDdobW4VkrHdqZW425+qxM0suRHFv1ruSphHOs7wKEL2gpmxcRgQSm3H/uIRGcL NlSnYsGfv8A8gxNxTyGSNaQbylRwJ/UasbOnWihTJFu3vGgarEfwlb+w2MId/xrE28pT /kOBc0LIhxQ+4OYiv0N/SvnGzpBXwGHtnu9OvNvH5h2y1l4dC4YN/b+EP01vFQQzMfUX 2jAA== 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=7U200FudwbpHutc22Z/SL8svBLcZPO5nI24IbArJq+8=; b=rc3Pf9ff/tVDDf2a54rbPWJNC2qxh0v8xIdpYKqm5gewLfAGH1y6o5jHNaSrCisrnN ItxOCxPTrIoHEJeL85XPLBouIUkYyoSBqiYqykRHzfnGnVnBfwOr3lh7knwJD/YZ/lF+ qU5lGPUk0Gu5Z9SH0qiClp0JLC2SY1cYWkJ4JDWQbvk7Eq11+8YBdBJ8b4yEyYugYExC D6DL72i+ZJp+UKCtDXrIE2PPvISCzbLunC+vn/soo6pagdvSqW4aP/vV3zML5RFTRtzh I/LgDcUsQy4NmolHbJwrRBC9rgEE6ZgRR3l7tzG3ouu7g6si0rgUpuaQfplZZFYPwLmB P6xA== X-Gm-Message-State: ACrzQf0sWPdzw2ebgJpqhQO7vi5gCEskbwPlQ5wrmBjeeGFr/lEOx447 221apX1iWVwVg9BSHqEYX51zNNgcjYgcQA== X-Google-Smtp-Source: AMsMyM50fuEEPN+cWyc+FtyknQXNmFTnluoXKwq2ETCyaVehpktaZH7FWLpjBJaBxlNp3aXaHUuoGw== X-Received: by 2002:a17:902:f68f:b0:179:e82d:a0a2 with SMTP id l15-20020a170902f68f00b00179e82da0a2mr2404327plg.16.1664440656247; Thu, 29 Sep 2022 01:37:36 -0700 (PDT) Received: from roots.. ([112.44.202.63]) by smtp.gmail.com with ESMTPSA id s5-20020a170902ea0500b0017829a3df46sm5324233plg.204.2022.09.29.01.37.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 01:37:36 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: damien.lemoal@opensource.wdc.com, Kevin Wolf , hare@suse.de, Hanna Reitz , Markus Armbruster , Fam Zheng , stefanha@redhat.com, Eric Blake , qemu-block@nongnu.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v10 6/7] qemu-iotests: test new zone operations Date: Thu, 29 Sep 2022 16:36:30 +0800 Message-Id: <20220929083631.61899-7-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220929083631.61899-1-faithilikerun@gmail.com> References: <20220929083631.61899-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=faithilikerun@gmail.com; helo=mail-pj1-x102b.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 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 | 86 ++++++++++++++++++++++++++++++ 2 files changed, 139 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..fced0194c5 --- /dev/null +++ b/tests/qemu-iotests/tests/zoned.sh @@ -0,0 +1,86 @@ +#!/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 "case 1: 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 Thu Sep 29 08:36:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 12993717 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 44C90C07E9D for ; Thu, 29 Sep 2022 08:58:09 +0000 (UTC) Received: from localhost ([::1]:46488 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1odpMt-0004Bb-9Z for qemu-devel@archiver.kernel.org; Thu, 29 Sep 2022 04:58:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51260) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1odp3I-0000kw-Hr; Thu, 29 Sep 2022 04:38:05 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]:36534) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1odp3E-0007mI-8C; Thu, 29 Sep 2022 04:37:52 -0400 Received: by mail-pf1-x435.google.com with SMTP id y136so842582pfb.3; Thu, 29 Sep 2022 01:37:45 -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=M31EW5S6vG1yBLEmkW0Pm4rG7QGT7vbmcxx33vJeyFw=; b=J3bP1TUePMC4/Y1XI5LC+A1J52nXehPyKAN5brorPDhyjZ5HDrD6iM5AhE5XjhJ+Jv A+aP6GwxuiauJN5IFOkw2ZVkOIoB/NkqFhXc8W0yu4RTiE2HlTdjJeajPUa98PjHJksu y2MPZbbFyPU00N+PmOwTVLRG2MHRNutMjiRVGyYt/6atZmiA6Qp+Zojl9FfqKZThMOOp wkgq+/9OjsNYngs0CSEGhD875gQ07+2xWmj2Ik2zAkpq+Rfdj9CtiV9AFKRFb3mzRN4i vgiKT+K7lZtRW89U/yy/4dl27ulaWTI47QbLviQ7xhfF+Lb/5IdtvW+ZYbvPxMQkGumc 6s6g== 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=M31EW5S6vG1yBLEmkW0Pm4rG7QGT7vbmcxx33vJeyFw=; b=3rIZAD3/qNCMXDmhXXXoNX6LFI9PbsDcp8S0wvOsjQTjmmP5uxnRpPCCY3ATEtZp7T uWLBATqhwZbyyOzSPZTKZHv0ikvkDsflC2D1kTnSw6VwfuikFZ9ZX6hpUvW2o2oJZNzc Y5Ue7sUNbiIsOdoWVU0hsVeFSmPkI3D9wW6AYE9IpUGwsDmaiGQQlDGUJsKd8k3zCMeW Z9JQL22LKXbmEw/s2C5+AAtAsnkDgWGY0iutuFyPCBVuF2qTA/9KuInx7yTDKJp2dv6P W0TNHT7invtsLAs6ClJaEHDQNrXDnTdX3gL3hAx3fb65GD25Bn2HO0/iDuM1FzpbwCSW J/Vw== X-Gm-Message-State: ACrzQf2ofukatH4h2OcPEfVpliGHa9Qq/BSnun5IJc+YoTtfZvzxmrp5 5bFNVyn9SshXCE/ktNziY/jjgHvBUfF9xw== X-Google-Smtp-Source: AMsMyM4/pt87q6oqldWyPu7VWrD0y3mVDe6EsVampqejGwNSQzixv6uGwAf2lHgsFzeSs4mjtTuBbQ== X-Received: by 2002:a63:f5e:0:b0:434:d532:aad4 with SMTP id 30-20020a630f5e000000b00434d532aad4mr1890958pgp.175.1664440664027; Thu, 29 Sep 2022 01:37:44 -0700 (PDT) Received: from roots.. ([112.44.202.63]) by smtp.gmail.com with ESMTPSA id s5-20020a170902ea0500b0017829a3df46sm5324233plg.204.2022.09.29.01.37.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Sep 2022 01:37:43 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: damien.lemoal@opensource.wdc.com, Kevin Wolf , hare@suse.de, Hanna Reitz , Markus Armbruster , Fam Zheng , stefanha@redhat.com, Eric Blake , qemu-block@nongnu.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v10 7/7] docs/zoned-storage: add zoned device documentation Date: Thu, 29 Sep 2022 16:36:31 +0800 Message-Id: <20220929083631.61899-8-faithilikerun@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220929083631.61899-1-faithilikerun@gmail.com> References: <20220929083631.61899-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=faithilikerun@gmail.com; helo=mail-pf1-x435.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 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 | 40 ++++++++++++++++++++++++++ docs/system/qemu-block-drivers.rst.inc | 6 ++++ 2 files changed, 46 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..deaa4ce99b --- /dev/null +++ b/docs/devel/zoned-storage.rst @@ -0,0 +1,40 @@ +============= +zoned-storage +============= + +Zoned Block Devices (ZBDs) devide the LBA space into block regions called zones +that are larger than the LBA size. They can only allow sequential writes, which +can reduce write amplification in SSDs, and potentially lead 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, to test zone_report on a null_blk device using qemu-io is: +$ path/to/qemu-io --image-opts -n 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 ^^^^^^^