From patchwork Thu Oct 27 15:44: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: 1695487 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=LafuTTtV; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Myqq60Tq0z23kj for ; Fri, 28 Oct 2022 02:49:04 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo555-00020U-2U; Thu, 27 Oct 2022 11:46:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo54p-0000Vd-Lc; Thu, 27 Oct 2022 11:45:55 -0400 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo54X-00011D-44; Thu, 27 Oct 2022 11:45:39 -0400 Received: by mail-pf1-x42a.google.com with SMTP id i3so1921555pfc.11; Thu, 27 Oct 2022 08:45: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 :message-id:reply-to; bh=c5hXkEGI882XKLcRqYRJTkqwhEoqEQQdvijOpbi79NI=; b=LafuTTtVBWhmqj8bZkuvCCszQrl3E7OqMfhQy3mh6wgBK/QMnsjZyJK0O5yhhQfDR5 9MscuKyX9f9BUH1oDww1DvU2FrqyFUKg1s5KVdL5v6mFEAWyFcWZFf9HZ2MFwvLYv0M/ s2f34BSeYOy4zJrzZ9AJgm0p2ciF5KpATsSU9eYZL0/PGqE/fSl24vVS8IjrHC9ROdQg +ciCBav814pvI1G416HkNW7mdjRj7TzH24kXB8TEUnkL1r92j7LyOMbApCscvCvX3NQH PFP2MOU/a56+f+h3cQABmuF79apQ1jvzvs24/17evVweAfV0yjuLagqhxUZTb9YSbysW jOkw== 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:message-id:reply-to; bh=c5hXkEGI882XKLcRqYRJTkqwhEoqEQQdvijOpbi79NI=; b=e7geOTp9tQWFwRBS+Nf2+buM+A9lMHy7H43CfbgvofUAEGkJa2b6lGVch0NqR+5Kv0 TiRHfXP9Eql19mslVX58ZqZjeXhvhSQC9EYyGMAGNpt7fJjsuHxlrJhzxDX/U2CODDxc DxcAipof2KsAoM7NOORx4YQG3A+vjLq9x3tLIhRMNQLcdJW0ECoibcczjUVqn7hBjvYE p/Ddyx09JIgTyhkezZ6E5J/0txwEArb8F6zitpsnpSFv7UQ3loAg6fxDcHfd/6JiwUO9 +C0QepvscGjpK96fKmihtS67NyXeOt1wTSzkb/y6jtSq+yLRs/+iw8r3vXJ42AlxarnV 2Jxw== X-Gm-Message-State: ACrzQf26kusLLS24I5krjKecx1QhX+K7UvUmcW7HwIpkIktTzdek6Shb wJp8Sb8ghwmO8TPsvyxEp4ZAcPXA5k5gNzxz X-Google-Smtp-Source: AMsMyM6NHPuDLDcr5umq+4EmhzO0KzYabXqs5+IgM4dHYruR56/pZSfR6Wj/23QC86T2b+hzdoS2mg== X-Received: by 2002:a05:6a00:4c9c:b0:56b:a9bd:ee4f with SMTP id eb28-20020a056a004c9c00b0056ba9bdee4fmr25069629pfb.35.1666885528114; Thu, 27 Oct 2022 08:45:28 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.45.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:45:27 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 1/8] include: add zoned device structs Date: Thu, 27 Oct 2022 23:44:57 +0800 Message-Id: <20221027154504.20684-2-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42a; envelope-from=faithilikerun@gmail.com; helo=mail-pf1-x42a.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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke --- 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..4025df380e 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 BlockZoneState { + 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, +} BlockZoneState; + +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; + BlockZoneState state; +} BlockZoneDescriptor; + typedef struct BlockDriverInfo { /* in bytes, 0 if irrelevant */ int cluster_size; From patchwork Thu Oct 27 15:44: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: 1695491 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=ErbE84Oa; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Myqrp1wjnz23kp for ; Fri, 28 Oct 2022 02:50:34 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo54v-0000wD-Pc; Thu, 27 Oct 2022 11:45:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo54r-0000Vk-IL; Thu, 27 Oct 2022 11:45:55 -0400 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo54c-00013p-6L; Thu, 27 Oct 2022 11:45:46 -0400 Received: by mail-pl1-x634.google.com with SMTP id n7so1930384plp.1; Thu, 27 Oct 2022 08:45: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 :message-id:reply-to; bh=R2mJnjpcL3xEm+xhC8qiDzUKjlvtfd7jwLm78mbcKIo=; b=ErbE84OaBfXWc9UeTJ/0eD35tKlEOc0TL6KL5/gR0rxt2NrmwSh27uCClVpFnlx98M 3oqoySfVp3v3EGSA/2uaqbM9171DU86kRZAzMguSikiyaTin6Z3ixAoNemJaW6cPn0fp 5n5GiBDvmjArnoTvL6FsGBQ68Ayn5kmbCgxo51h776yqmmUDySuXJjZv7vcyxz8S+x5s Xy3lpg0IUjIkc2rh3+QSe2pKPPvUUWaFgP0pOurE8BNEXrfYfGhhqx7maW/uJ0EMH3wH +G4OkYECW02HKxNJgS7uS1nB6sCk33tOTaarAzY3nL3lkHe1LuF/4X5KUS+4ZucUvRfT lkeg== 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:message-id:reply-to; bh=R2mJnjpcL3xEm+xhC8qiDzUKjlvtfd7jwLm78mbcKIo=; b=X4BZL63VFliXrAfNOJgYJsrdX7k93AjBQnAl+g/RHUB5KzaBi7710m5PEUoELyrsNV loeXTIeWxF4XdJN6pmQ2Elp4y53fpMkkC/6LeF4DtNuK7Vn45M6GFcsfOB/U9WkINKcu BIat0ZbkLehg8m7RY/RNsqqabQJP5tIsR/JtEp3d5itSbHTkrMvnqyJz/ugZvoD7y45g DL7lQ1HT3Bk6OVtVmA0kJ+GFAs5VNJnIL/ZEBAhInH0nx2oG41noVH563tquU0W8RGwF M4zx3gUwa2RWphrm4Ru6RPnOGL2/BpR3saiiwgh7wRKthAKoGJiONBLkul+SP/JSL8Uf AcCA== X-Gm-Message-State: ACrzQf1b3nSoopmaWOc4A3MaqKTf2lBPaKO6UkR12wFG56ldXtVmAnxD HuttdIFYRzJex51oT7red1Mq0xZW41k2x+nx X-Google-Smtp-Source: AMsMyM7chBDQNPc7gk62PmL5S3CDhI3s3pa2UJQaMre+L+VNxVUm0yxOP0UofBEU+2RLPppDfbtdUA== X-Received: by 2002:a17:902:f786:b0:186:7a6b:217c with SMTP id q6-20020a170902f78600b001867a6b217cmr33127410pln.55.1666885535854; Thu, 27 Oct 2022 08:45:35 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.45.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:45:35 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 2/8] file-posix: introduce helper functions for sysfs attributes Date: Thu, 27 Oct 2022 23:44:58 +0800 Message-Id: <20221027154504.20684-3-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-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 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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Reviewed-by: Dmitry Fomichev --- block/file-posix.c | 124 ++++++++++++++++++++++--------- include/block/block_int-common.h | 3 + 2 files changed, 91 insertions(+), 36 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index 23acffb9a4..8cb07fdb8a 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1201,66 +1201,112 @@ 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); @@ -1298,6 +1344,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 Oct 27 15:44: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: 1695499 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=hn7r1ItV; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MyqzX333Gz1ygr for ; Fri, 28 Oct 2022 02:56:24 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo54x-0001L3-I7; Thu, 27 Oct 2022 11:45:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo54u-0000mS-9a; Thu, 27 Oct 2022 11:45:56 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo54p-00014G-Ur; Thu, 27 Oct 2022 11:45:56 -0400 Received: by mail-pj1-x102c.google.com with SMTP id d13-20020a17090a3b0d00b00213519dfe4aso1828246pjc.2; Thu, 27 Oct 2022 08:45: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 :message-id:reply-to; bh=0oLOZ0FuJlMskAeMDQkw/PsKKrIIRbkYEFCf5XAPIw4=; b=hn7r1ItVOCMmV6VxnZ07Lp5wZ8Nph6MqR9oh8hzBMiul0IFVzTaiaJO0Iu6zxa6cer /Lbxswy+n+weULb5dlZIMmaUXsF6HwdZxmHc3Zj9M0z96pYWsHXlx052WXBAG/BP4JV5 Buo24dYJwEotegllJdNsu42lFwkJEK7VneAtV2CgYd2p5WjBS2fyIb/1x+AWrVsv1Vnb GQoLxbB7NZ8uAu3pXmDZ4EeNT9WElidnkezG6LB9qV3YFE0f2bvyLtNE9FYMO+ffOCiR JgtIxI47O+MIlYohizAUX5bBv+Z1lAlFhCm0nhAuTm7zhtxn1ccbOf3CZt/Hb640z7ua jaoQ== 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:message-id:reply-to; bh=0oLOZ0FuJlMskAeMDQkw/PsKKrIIRbkYEFCf5XAPIw4=; b=DtG6tl185Xfkt1FlxsjPXx33K5rFHDsgvcfNcv9WDQmvkgfWRa+/Uth5jSHR6aXXFq aqQx2BcgU020TIBFDOthfH9qB9p58O/VN0Vmk/tCQlUKYcn0SwOsPVdxWZqQ6Vm9OJEP js/WfQTcyk8j8dZQb0U8nuJqQVVvUc/48cIOelejCl5g8KKJyEtCKrXdYoXgiWCQJvot u9H2UWp/oTPF2TOhphw4GMy2UBkgD/VnXu2vrXHx6yfxbwDxxE6rKoT//WT8zD1CA3Gg fYz8UwvdrprFqCjqZJ6SVTnE4Q+qrUsahcEU6jTTJCUocE1p+Fn8y/SN1DrSRb+dY6hE ipXA== X-Gm-Message-State: ACrzQf0siGVk2Z8eeZ4g30biCNfgQjE7Fe/ZU3PZsf7dg23QsVvgL5Yn YTzfV1WVshaWAnOIXzTCn8r0pBNHM7EpUzEN X-Google-Smtp-Source: AMsMyM4xMbqomynRnXWE/pIa4R3kXZNve8qIFM9iv89wPggySITt1egWyW+7GaLyDcazw75NNGLyNg== X-Received: by 2002:a17:90b:4d07:b0:1ef:521c:f051 with SMTP id mw7-20020a17090b4d0700b001ef521cf051mr11118151pjb.164.1666885544106; Thu, 27 Oct 2022 08:45:44 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.45.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:45:43 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 3/8] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls Date: Thu, 27 Oct 2022 23:44:59 +0800 Message-Id: <20221027154504.20684-4-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=faithilikerun@gmail.com; helo=mail-pj1-x102c.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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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, reset_all). 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 | 147 +++++++++++++ block/file-posix.c | 348 ++++++++++++++++++++++++++++++ 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 | 18 ++ meson.build | 4 + qapi/block-core.json | 8 +- qemu-io-cmds.c | 149 +++++++++++++ 10 files changed, 746 insertions(+), 3 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index aa4adf06ae..731f23e816 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 { + unsigned long op; + } zone_mgmt; + }; } BlkRwCo; int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags) @@ -1775,6 +1784,144 @@ int coroutine_fn blk_co_flush(BlockBackend *blk) return ret; } +static void coroutine_fn 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 coroutine_fn 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 8cb07fdb8a..5f56526348 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 @@ -215,6 +218,13 @@ typedef struct RawPosixAIOData { PreallocMode prealloc; Error **errp; } truncate; + struct { + unsigned int *nr_zones; + BlockZoneDescriptor *zones; + } zone_report; + struct { + unsigned long op; + } zone_mgmt; }; } RawPosixAIOData; @@ -1350,6 +1360,50 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) zoned = BLK_Z_NONE; } bs->bl.zoned = zoned; + if (zoned != BLK_Z_NONE) { + /* + * The zoned device must at least have zone size and nr_zones fields. + */ + ret = get_sysfs_long_val(&st, "chunk_sectors"); + if (ret < 0) { + error_setg_errno(errp, -ret, "Unable to read chunk_sectors " + "sysfs attribute"); + goto out; + } else if (!ret) { + error_setg(errp, "Read 0 from chunk_sectors sysfs attribute"); + goto out; + } + bs->bl.zone_size = ret << BDRV_SECTOR_BITS; + + ret = get_sysfs_long_val(&st, "nr_zones"); + if (ret < 0) { + error_setg_errno(errp, -ret, "Unable to read nr_zones " + "sysfs attribute"); + goto out; + } else if (!ret) { + error_setg(errp, "Read 0 from nr_zones sysfs attribute"); + goto out; + } + bs->bl.nr_zones = ret; + + ret = get_sysfs_long_val(&st, "zone_append_max_bytes"); + if (ret > 0) { + bs->bl.max_append_sectors = ret >> BDRV_SECTOR_BITS; + } + + 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; + } + return; + } +out: + bs->bl.zoned = BLK_Z_NONE; } static int check_for_dasd(int fd) @@ -1374,9 +1428,11 @@ static int hdev_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz) int ret; /* If DASD, get blocksizes */ +#ifndef CONFIG_BLKZONED if (check_for_dasd(s->fd) < 0) { return -ENOTSUP; } +#endif ret = probe_logical_blocksize(s->fd, &bsz->log); if (ret < 0) { return ret; @@ -1844,6 +1900,146 @@ 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 int parse_zone(struct BlockZoneDescriptor *zone, + const struct blk_zone *blkz) { + zone->start = blkz->start << BDRV_SECTOR_BITS; + zone->length = blkz->len << BDRV_SECTOR_BITS; + zone->wp = blkz->wp << BDRV_SECTOR_BITS; + +#ifdef HAVE_BLK_ZONE_REP_CAPACITY + zone->cap = blkz->capacity << BDRV_SECTOR_BITS; +#else + zone->cap = blkz->len << BDRV_SECTOR_BITS; +#endif + + 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: + error_report("Unsupported zone type: 0x%x", blkz->type); + return -ENOTSUP; + } + + switch (blkz->cond) { + case BLK_ZONE_COND_NOT_WP: + zone->state = BLK_ZS_NOT_WP; + break; + case BLK_ZONE_COND_EMPTY: + zone->state = BLK_ZS_EMPTY; + break; + case BLK_ZONE_COND_IMP_OPEN: + zone->state = BLK_ZS_IOPEN; + break; + case BLK_ZONE_COND_EXP_OPEN: + zone->state = BLK_ZS_EOPEN; + break; + case BLK_ZONE_COND_CLOSED: + zone->state = BLK_ZS_CLOSED; + break; + case BLK_ZONE_COND_READONLY: + zone->state = BLK_ZS_RDONLY; + break; + case BLK_ZONE_COND_FULL: + zone->state = BLK_ZS_FULL; + break; + case BLK_ZONE_COND_OFFLINE: + zone->state = BLK_ZS_OFFLINE; + break; + default: + error_report("Unsupported zone state: 0x%x", blkz->cond); + return -ENOTSUP; + } + return 0; +} +#endif + +#if defined(CONFIG_BLKZONED) +static int handle_aiocb_zone_report(void *opaque) +{ + 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 */ + uint64_t sector = aiocb->aio_offset / 512; + + struct blk_zone *blkz; + size_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++) { + ret = parse_zone(&zones[n], &blkz[i]); + if (ret != 0) { + return ret; + } + + /* The next report should start after the last zone reported */ + sector = blkz[i].start + blkz[i].len; + } + } + + *nr_zones = n; + return 0; +} +#endif + +#if defined(CONFIG_BLKZONED) +static int handle_aiocb_zone_mgmt(void *opaque) +{ + RawPosixAIOData *aiocb = opaque; + int fd = aiocb->aio_fildes; + uint64_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.op, &range); + } while (ret != 0 && errno == EINTR); + + return ret; +} +#endif + static int handle_aiocb_copy_range(void *opaque) { RawPosixAIOData *aiocb = opaque; @@ -3038,6 +3234,107 @@ 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. + */ +#if defined(CONFIG_BLKZONED) +static int coroutine_fn raw_co_zone_report(BlockDriverState *bs, int64_t offset, + unsigned int *nr_zones, + BlockZoneDescriptor *zones) { + 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); +} +#endif + +/* + * zone management operations - Execute an operation on a zone + */ +#if defined(CONFIG_BLKZONED) +static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, + int64_t offset, int64_t len) { + BDRVRawState *s = bs->opaque; + RawPosixAIOData acb; + int64_t zone_size, zone_size_mask; + const char *op_name; + unsigned long zo; + int ret; + int64_t capacity = bs->total_sectors << BDRV_SECTOR_BITS; + + 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) < capacity && len & zone_size_mask) || + offset + len > 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: + op_name = "BLKOPENZONE"; + zo = BLKOPENZONE; + break; + case BLK_ZO_CLOSE: + op_name = "BLKCLOSEZONE"; + zo = BLKCLOSEZONE; + break; + case BLK_ZO_FINISH: + op_name = "BLKFINISHZONE"; + zo = BLKFINISHZONE; + break; + case BLK_ZO_RESET: + op_name = "BLKRESETZONE"; + zo = BLKRESETZONE; + break; + default: + error_report("Unsupported zone op: 0x%x", op); + return -ENOTSUP; + } + + acb = (RawPosixAIOData) { + .bs = bs, + .aio_fildes = s->fd, + .aio_type = QEMU_AIO_ZONE_MGMT, + .aio_offset = offset, + .aio_nbytes = len, + .zone_mgmt = { + .op = zo, + }, + }; + + ret = raw_thread_pool_submit(bs, handle_aiocb_zone_mgmt, &acb); + if (ret != 0) { + ret = -errno; + error_report("ioctl %s failed %d", op_name, ret); + } + + return ret; +} +#endif + static coroutine_fn int raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes, bool blkdev) @@ -3768,6 +4065,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) @@ -4028,6 +4373,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 d30073036e..88f707ea4d 100644 --- a/block/io.c +++ b/block/io.c @@ -3189,6 +3189,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-io.h b/include/block/block-io.h index 492f95fc05..f0cdf67d33 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..c844ec3cf7 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 bytes */ + uint32_t zone_size; + + /* total number of zones */ + uint32_t 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..877b2240b3 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..1b5fc7db6b 100644 --- a/include/sysemu/block-backend-io.h +++ b/include/sysemu/block-backend-io.h @@ -45,6 +45,13 @@ 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 +163,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 44c1f92697..0aa99b64a0 100644 --- a/meson.build +++ b/meson.build @@ -1928,6 +1928,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')) @@ -2021,6 +2022,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 882b266532..05a3b44731 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..3a3bad77c3 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1712,6 +1712,150 @@ 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].state, 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 +2648,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 Oct 27 15:45:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 1695497 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=MtWS/aTA; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MyqxY2VlLz20S2 for ; Fri, 28 Oct 2022 02:54:39 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo557-0002EK-Sj; Thu, 27 Oct 2022 11:46:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo54z-0001hy-8M; Thu, 27 Oct 2022 11:46:06 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo54t-00016y-WC; Thu, 27 Oct 2022 11:46:01 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d24so1920693pls.4; Thu, 27 Oct 2022 08:45:53 -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 :message-id:reply-to; bh=xDdFVSm8ncoeSJJtfyHTb4bkGYhcGVxibxrd/95vTWc=; b=MtWS/aTAVTZIb0hzc5XGg5HSnN9TICnM+n7pFGtv5mM1oqYOSdALZj45Y/L0k1P3Iz TqDHZPgkuOeqQpkenTR6irsgjs6oIYDPztgRnRnKOnKcWCZODkoXf8GHFdNKoPUtydYQ OSY6iGcGxbf4GXRmFmrvyhY4BrwtBNHvQs8QU6m2jPh2iW0q6YYyWOubKwP3/nV7v+kH sWYSuiU3Kpsk6oZaazjGArF4KWXdUg8jk3Y47IBeDbepk421M2nALjHFHuwWOwJSjWLu chA32AGa7hKLGJUSuG9qL1BgRUYyOPUgoCtthFfUFiazsYDrBm7Z+m0zu/iTI3oZW7Ex AtYg== 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:message-id:reply-to; bh=xDdFVSm8ncoeSJJtfyHTb4bkGYhcGVxibxrd/95vTWc=; b=DtjWaZBy56jtr/g+Qmxaxamn2z8eNY2ovmK5WWZRJm2JVbXWi5YlHQPInsc0Byi2Uz 989KlFPEpk46eREOlE83Dy/Mxb9vctfiVMC7HUs0ymefFlSVBp22LZfwi5avP6ELt7qJ 56mxHjeBIvb508qHlAPce9php4efagElZpFqlLPG5oHo8xUhn07YIqhRvVZhBp52yx6h h19isrItReccFGWdf4f+3p72Fi9WbkHO2JG6uDPHK2YrgJH6/ziQpsDgPGipxyAzoJ56 RhtM7T+nho3DUrDymkhCV2Db+xI7a8yvkN8AdxDJ0lzJfL7NGqfQ7u96Y4xtcnVnrjvy YBRg== X-Gm-Message-State: ACrzQf0xGET/crUEKcdO7Z3CU08TDZbCvYMjuv0rwMf7kp3yp76OdRtW Diy0hFdIqD3bjP/Oq2mcDGykGmnYREzbjVGt X-Google-Smtp-Source: AMsMyM6HplgD5XVEJVv2QedjxS/rOjmf2YWFOulV0OQUFyQ0QfT++PEmJpEFqpXZSrqS//fxKaUVMA== X-Received: by 2002:a17:90a:cb96:b0:213:1dc2:b1de with SMTP id a22-20020a17090acb9600b002131dc2b1demr10567344pju.21.1666885551955; Thu, 27 Oct 2022 08:45:51 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.45.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:45:51 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 4/8] raw-format: add zone operations to pass through requests Date: Thu, 27 Oct 2022 23:45:00 +0800 Message-Id: <20221027154504.20684-5-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=faithilikerun@gmail.com; helo=mail-pl1-x62b.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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 Reviewed-by: Hannes Reinecke Reviewed-by: Dmitry Fomichev --- block/raw-format.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/block/raw-format.c b/block/raw-format.c index f337ac7569..bac43f1d25 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; @@ -615,6 +626,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 Oct 27 15:45:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 1695488 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=TF8xwy0G; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MyqrK5T52z1ygr for ; Fri, 28 Oct 2022 02:50:09 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo558-0002M7-Ns; Thu, 27 Oct 2022 11:46:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo553-0001zO-FC; Thu, 27 Oct 2022 11:46:06 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo54z-00018g-H4; Thu, 27 Oct 2022 11:46:04 -0400 Received: by mail-pj1-x1031.google.com with SMTP id m14-20020a17090a3f8e00b00212dab39bcdso6902734pjc.0; Thu, 27 Oct 2022 08:46:00 -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 :message-id:reply-to; bh=f+iLtgJkxPaaEAC5I4tM8ivVOwvQH6OVtQJbShZ1HII=; b=TF8xwy0Gp4AQf6TeGoYEqB5ICrlbBOrRLfqVPxxKFk/xv9qCg6ZSPM9j3FLXxkupMx l53chX9r73OVmrH8OWjThC/iu/YvxD202PIj8pnbUK++hXRv9aFJBwqRdlh1cr70RuNc qnFXBUC2kwK6vxy9Z4PtD96YP5gVdgJFF53EDlRX/T5ZKBnkVSWVBSlroVvSbezgSi7I Y7n2AK5SIbuxkNEaNCqNyGE8tfUkpVCs42T/zdk8XSl4KTz2b4s4UqtUWeoFa2iLo6v2 U48S77ZWPzYDlk6zpoK5FR1zCD+4Bs6aJSa78oRJO71lGL26FDKP9RK1IbLO0SrNzEbA Ud6A== 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:message-id:reply-to; bh=f+iLtgJkxPaaEAC5I4tM8ivVOwvQH6OVtQJbShZ1HII=; b=S/ltm0Gu7ABNId+eAim6xYdNmrBMZfbYw4T/OApkQGDkGBSlLpYoFn9SoadZaXkWbn R25YDzlkDPGMnOycZ1dDkhaSC9GrHQceDDQLj57i/Wg8GfiN5qhk+vjRFw2Xo/JEAxSs EncdFCJmbIRxaAJLoGcy6WFBY8NDD5NFCqekJUHa2zfoxWoBCE6BK3XEjxFCpd8nT7mX TRnHMxLD3z4IZGc2/5uXrv07Pc0BNJqtKnnPVdhSKlIZ6kXC+h/mrkF7umCfd5qkxNeE e2oIYkSCaTjI9FeryZF/MsNP1ayBH45x8FPzHdSpNmclsiniYmnOwPNm3svw3O7y9EsK bMAA== X-Gm-Message-State: ACrzQf1whCrOs/1qSTf5Xp6/G46zDfYvQxK3rgAULjsHMGHtaBsa2ppS qu4DXSqvELvAthJGeuZPH1desPbnk8D5V6L8 X-Google-Smtp-Source: AMsMyM67PvWgFajKbDYcvQqjwy8/sDA8czUV1ExGvIziVJVpKD8Ngfl/hD3gazaaQ1KCYTBLbkl+qQ== X-Received: by 2002:a17:903:50e:b0:182:631b:df6f with SMTP id jn14-20020a170903050e00b00182631bdf6fmr50075316plb.66.1666885559329; Thu, 27 Oct 2022 08:45:59 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.45.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:45:59 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 5/8] config: add check to block layer Date: Thu, 27 Oct 2022 23:45:01 +0800 Message-Id: <20221027154504.20684-6-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=faithilikerun@gmail.com; helo=mail-pj1-x1031.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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Putting zoned/non-zoned BlockDrivers on top of each other is not allowed. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi Reviewed-by: Hannes Reinecke Reviewed-by: Dmitry Fomichev --- block.c | 19 +++++++++++++++++++ block/file-posix.c | 12 ++++++++++++ block/raw-format.c | 1 + include/block/block_int-common.h | 5 +++++ 4 files changed, 37 insertions(+) diff --git a/block.c b/block.c index 1fbf6b9e69..5d6fa4a25a 100644 --- a/block.c +++ b/block.c @@ -7951,6 +7951,25 @@ 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) { + /* + * 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. + */ + 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 5f56526348..02476c011e 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -775,6 +775,18 @@ 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) && + (!(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 __linux__ diff --git a/block/raw-format.c b/block/raw-format.c index bac43f1d25..18dc52a150 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -615,6 +615,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 c844ec3cf7..2c057a9980 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 Oct 27 15:45:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 1695492 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=aaseu7VS; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Myqv24Mnvz20S2 for ; Fri, 28 Oct 2022 02:52:30 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo55C-0002Yo-DS; Thu, 27 Oct 2022 11:46:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo55A-0002XM-SR; Thu, 27 Oct 2022 11:46:12 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo557-0001Dy-W2; Thu, 27 Oct 2022 11:46:12 -0400 Received: by mail-pj1-x102a.google.com with SMTP id pb15so1918585pjb.5; Thu, 27 Oct 2022 08:46:09 -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 :message-id:reply-to; bh=4UDRne5xZbwbkxQ2/0o7lRb66oYqvDKMKGME0yjIxmY=; b=aaseu7VSizMYRU+Bskc+V9aR4X64cKShNyiMB/GMYJDwyeYEx+2U0vovJFXVrLVeeo Isa1R+ZQ1aWhMpMUtGdiCGYM/sW4M5Y+Q6TkXfmbqiL15L0kt06TxHw87XtqXtyDQOOB RKkuMGgoGnWZyzms+XbxiyXrVVDNk/zH8pyqHmo+or+2Gz1gcV7+4KLrlutfwK9kisnI o6WhiPHBvnbHFEh6qJzA8an/PYFObhit/LmGSKs9Z4AiEMeN0totVGfVXbAxO8deDb63 tU1eyDPZ7PYSIMKNK/9ptRr2i7uxA3r/mqgDfFhUsKUJkPTrrIT3GTNMuhqtArEH7ijI vnDw== 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:message-id:reply-to; bh=4UDRne5xZbwbkxQ2/0o7lRb66oYqvDKMKGME0yjIxmY=; b=uqx9N7jpdKhsQofSS3Mqnm+8cFsRNx9Gm+TApfP8ibDAvfP29FLGbyA+0S5RQ8HnhB W45OzeuCqqtSOPKOhp5/JA2GW8GH1o+q9bg8S97kKuvM7yvNQuQ7Kfweq/gft9HAIEa9 Fyfl3SHnwk8Da3ZOf8+Ga9bHb8+XgWcEokntF+JXakRdgEHb6c+rW5pGIngClZhXhBxB 4fv3Gx5S2o4dsRwAozSX8QN6moSoIf+VMlVzzqaDZyezONCVcj0HVEYYbc0HeYQujX5m mldTc0n4dkYedHNVa2J54wofdqbncVGY0dO33O3u0U9hakYBQw/RfFTJvLQDAarjBV/E GB8g== X-Gm-Message-State: ACrzQf004coHUP0sOwcQ56OfEB1Le9CFfGdRG2w5skWrV2yHdRZiLn6y EEuzL1vycWmqYVcPcph9N3rJZ9wKHaGZdb7j X-Google-Smtp-Source: AMsMyM6kITwWHFIIo9O4L7QDb6nChZS81ar+I5Vw6Ji+MoiNKGDxcIBzzA9pLecTZVzN+GSxPIi1Ow== X-Received: by 2002:a17:902:ce12:b0:17a:3e76:8568 with SMTP id k18-20020a170902ce1200b0017a3e768568mr50106984plg.11.1666885566759; Thu, 27 Oct 2022 08:46:06 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.45.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:46:06 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 6/8] qemu-iotests: test new zone operations Date: Thu, 27 Oct 2022 23:45:02 +0800 Message-Id: <20221027154504.20684-7-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=faithilikerun@gmail.com; helo=mail-pj1-x102a.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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org We have added new block layer APIs of zoned block devices. Test it as follows: Run each zone operation on a newly created null_blk device and see whether the logs show the correct zone information. By: $ ./tests/qemu-iotests/tests/zoned.sh 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 Oct 27 15:45:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 1695490 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=emLRHtRr; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Myqrn6m2mz20S2 for ; Fri, 28 Oct 2022 02:50:33 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo55J-0002bE-SU; Thu, 27 Oct 2022 11:46:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo55G-0002Ze-NS; Thu, 27 Oct 2022 11:46:20 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo55D-00016y-OU; Thu, 27 Oct 2022 11:46:18 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d24so1921853pls.4; Thu, 27 Oct 2022 08:46: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 :message-id:reply-to; bh=YnjcNNRonQR6sDedMg/p0/pqlQVkOnSSjXYVlccWeYk=; b=emLRHtRrvJVfnMcFMW1URklGMpxPEL6Pmv3dSeJeee+AzbPvy4TWn1DskAghN+tYIT kR9EjHEKKyImrGy+kwEIg9YS2HkfVYSR0+MAiBNS5Fmw1bdCYPZyzugXnsCzkkit+tcd BaNWoOf0Sq7HUVqGwUdzgjS1kaqXDsak6AirsSGnxm3WQQeLe5KknLpo5iRSEKR/S+bk Ep7BDIA17sN5V3KCCMZuKcdDTnVjrrK/X4nb/Rz7tvraUuIKHCW15QQYbsgB5zfHJ7qB Hr1kjxvedjvtBIioeusxuHJIQ5wkkSZoomOqi6e8SCzcLVYaqrAwBm9Jszl5Fnwd1Pxv giKA== 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:message-id:reply-to; bh=YnjcNNRonQR6sDedMg/p0/pqlQVkOnSSjXYVlccWeYk=; b=vyTNuIXgl7cPNICrVdFx2uoGevohlfouaOK+bdzBJmde/Xm/apnEkOGFcqhKSk9+st +O+aXd/p8r8Ssa3OsX8RbYcI0ZbO57h5pLK1DgPeGiCCqkQTyNN2oYmk73xOIC756E0e A7jCMfOB6ZjEtZa2OI9reTWEGsThwIcviy6X3UzaeVjHa0lEn9mhSRegHPxdlC/N26yp vbRNkDdt8Hr9BxhQUPQfEoFFJeLBL43U9amT/qIpyXcsrgr3C2qDZkESwg/tmMgCcPA2 8VhILiI3ivQHPyOzpOj3eKKBI3TQM4QCL4K2vpe5AO2HKp4/arBTsNuUI90N/M/ANVjy 9h3w== X-Gm-Message-State: ACrzQf07NK5bDTVQoriSDOGDN/50rA/IHzE/X5S/ixZgECtX26sYc+so +ZpAicjTQUz70L6P1YPlh5z2eRZ/eKReR+EB X-Google-Smtp-Source: AMsMyM7jpa5ckmnCm+eP5T5siLt/oGYATBhIO4FhE4IPyvEipIurTFo8Ufc8MY2VXZXWhLeSC8+jWg== X-Received: by 2002:a17:90b:110c:b0:205:cfeb:cfb with SMTP id gi12-20020a17090b110c00b00205cfeb0cfbmr11005500pjb.75.1666885574064; Thu, 27 Oct 2022 08:46:14 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.46.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:46:13 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 7/8] block: add some trace events for new block layer APIs Date: Thu, 27 Oct 2022 23:45:03 +0800 Message-Id: <20221027154504.20684-8-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=faithilikerun@gmail.com; helo=mail-pl1-x62b.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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi --- block/file-posix.c | 3 +++ block/trace-events | 2 ++ 2 files changed, 5 insertions(+) diff --git a/block/file-posix.c b/block/file-posix.c index 02476c011e..fe52e91da4 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -3259,6 +3259,7 @@ static int coroutine_fn raw_co_zone_report(BlockDriverState *bs, int64_t offset, BlockZoneDescriptor *zones) { BDRVRawState *s = bs->opaque; RawPosixAIOData acb; + trace_zbd_zone_report(bs, *nr_zones, offset >> BDRV_SECTOR_BITS); acb = (RawPosixAIOData) { .bs = bs, @@ -3337,6 +3338,8 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, }, }; + trace_zbd_zone_mgmt(bs, op_name, offset >> BDRV_SECTOR_BITS, + len >> BDRV_SECTOR_BITS); ret = raw_thread_pool_submit(bs, handle_aiocb_zone_mgmt, &acb); if (ret != 0) { ret = -errno; diff --git a/block/trace-events b/block/trace-events index 48dbf10c66..3f4e1d088a 100644 --- a/block/trace-events +++ b/block/trace-events @@ -209,6 +209,8 @@ file_FindEjectableOpticalMedia(const char *media) "Matching using %s" file_setup_cdrom(const char *partition) "Using %s as optical disc" file_hdev_is_sg(int type, int version) "SG device found: type=%d, version=%d" file_flush_fdatasync_failed(int err) "errno %d" +zbd_zone_report(void *bs, unsigned int nr_zones, int64_t sector) "bs %p report %d zones starting at sector offset 0x%" PRIx64 "" +zbd_zone_mgmt(void *bs, const char *op_name, int64_t sector, int64_t len) "bs %p %s starts at sector offset 0x%" PRIx64 " over a range of 0x%" PRIx64 " sectors" # ssh.c sftp_error(const char *op, const char *ssh_err, int ssh_err_code, int sftp_err_code) "%s failed: %s (libssh error code: %d, sftp error code: %d)" From patchwork Thu Oct 27 15:45:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 1695493 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=Xd7yLwxh; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Myqw80pJxz23kp for ; Fri, 28 Oct 2022 02:53:27 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oo55S-0002g4-T2; Thu, 27 Oct 2022 11:46:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oo55Q-0002d8-1z; Thu, 27 Oct 2022 11:46:28 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oo55L-0001LQ-L0; Thu, 27 Oct 2022 11:46:27 -0400 Received: by mail-pl1-x629.google.com with SMTP id c2so1899571plz.11; Thu, 27 Oct 2022 08:46:22 -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 :message-id:reply-to; bh=5xermXZz2dzDd2OOV3cCqQeQVqHekRDRYxUpyHfIJKs=; b=Xd7yLwxhtgzcSNfwIK5R9WTI1lqeut8pN80SGWV08iMsUql2cHF1IVsgG1sQjKKElu 1xFXwJYkGtxfz4AqJTH+VST0wrPWuNs3fcaso9iOL8dNkEnXyATqDo3owyLwN1F1u8Od G1ltiR7RzvcOv/xVESbBRU+YajjHvNuQ2Q1ocZpryYQuH3DgjIdGxsVvKgCD8ZxE9QVU N9/VhW8aKFxB4XA7FVefW5Ti8vZ4TDVqL/hNmTbKAVbdpc91YD0wnFdaZkfd9kVWwEkY cgmK6ERZ5Hv9uQ5Zn9HRXsdAIk4j0OZuPQ+2WPzx6242qxSvOihFlCEfY+4z2GqHfkUS z66A== 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:message-id:reply-to; bh=5xermXZz2dzDd2OOV3cCqQeQVqHekRDRYxUpyHfIJKs=; b=A6i/StWBfHZNWpKas3QDCVKS4RSnrZ5Xw0dIrONsEiKeAuck2nPLDzyEuKinzZ0i+C WSdzo4UgSiKsw+ONNFeIbh8iwIXf5VaJ5p0RqefWxQQhZyn+B0S3d5a5dM+MeRAuvdNR JAYGYXBPKCcEVD4Xlr+br9o9vEWXFOhKa31EDi05nBKsKBSpqZuZOGNw5cr8p1IeeKov 4fBwolxHKuNqx+zGkeYGqPH0Wjp+WU9dDY6qOQh6L198Iri7+VgYLuo7QLywB8wOaKxK vsBuupD6ikAiLf9YasmqH/yVxJD0czZ3BXUlzz+B5ATjWMzuszJLyAV8tArEOaBjB1w8 b5Zw== X-Gm-Message-State: ACrzQf3apK8SpGkkslWnGOhr3z5B4cPoEel+dSZ0xUwNCU7eSSTvlmhg XxEiViiQeTLOR6ATHt0CiQf8znHut/D3/Khf X-Google-Smtp-Source: AMsMyM4QmPSDSSr/4fY7PUF3+EwRFnpnu/RGA5tVjjPMCcse6PJ5URqOL3B6gR47YC+ceJB0yga8gA== X-Received: by 2002:a17:90a:4b02:b0:212:f63f:6deb with SMTP id g2-20020a17090a4b0200b00212f63f6debmr10951913pjh.241.1666885581421; Thu, 27 Oct 2022 08:46:21 -0700 (PDT) Received: from roots.. ([112.44.202.248]) by smtp.gmail.com with ESMTPSA id q9-20020a63d609000000b004405c6eb962sm1232801pgg.4.2022.10.27.08.46.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Oct 2022 08:46:21 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , Hanna Reitz , damien.lemoal@opensource.wdc.com, qemu-block@nongnu.org, stefanha@redhat.com, Markus Armbruster , hare@suse.de, Kevin Wolf , dmitry.fomichev@wdc.com, Eric Blake , Sam Li Subject: [PATCH v13 8/8] docs/zoned-storage: add zoned device documentation Date: Thu, 27 Oct 2022 23:45:04 +0800 Message-Id: <20221027154504.20684-9-faithilikerun@gmail.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221027154504.20684-1-faithilikerun@gmail.com> References: <20221027154504.20684-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=faithilikerun@gmail.com; helo=mail-pl1-x629.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: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add the documentation about the zoned device support to virtio-blk emulation. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi Reviewed-by: Damien Le Moal Reviewed-by: Dmitry Fomichev --- docs/devel/zoned-storage.rst | 43 ++++++++++++++++++++++++++ docs/system/qemu-block-drivers.rst.inc | 6 ++++ 2 files changed, 49 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..03e52efe2e --- /dev/null +++ b/docs/devel/zoned-storage.rst @@ -0,0 +1,43 @@ +============= +zoned-storage +============= + +Zoned Block Devices (ZBDs) divide 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 supports three zoned storage models: +- BLK_Z_HM: The host-managed zoned model only allows sequential writes access +to zones. It supports ZBD-specific I/O commands that can be used by a host to +manage the zones of a device. +- BLK_Z_HA: The host-aware zoned model allows random write operations in +zones, making it backward compatible with regular block devices. +- BLK_Z_NONE: The non-zoned model has no zones support. It includes both +regular and drive-managed ZBD devices. ZBD-specific I/O commands are not +supported. + +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 ^^^^^^^