From patchwork Tue Apr 4 15:32:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13200476 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 46713C6FD1D for ; Tue, 4 Apr 2023 15:33:51 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pjieY-0004Ve-Qt; Tue, 04 Apr 2023 11:32:58 -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 1pjieX-0004VA-Gn; Tue, 04 Apr 2023 11:32:57 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pjieU-0005gX-Kr; Tue, 04 Apr 2023 11:32:56 -0400 Received: by mail-pf1-x435.google.com with SMTP id cm5so15882094pfb.0; Tue, 04 Apr 2023 08:32:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680622372; 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=PDwFnbwAQ628E24lv/sil+v21rnO8HvTED6y6PCZ2dg=; b=lTCCeKIJI6HMj6akX9A6EGTuh2rGu9NmXzl10LG/1hJ6ER5S+HDe/7K4RsrJE/6wZu 7VBuKi48JjVSBGe2jlw9yy6f2O0CdIap50QWwF3BK11OcYNrX3v8Fd11g8P1R9OoDLN0 rA906zhPaQM1A8fDty+VNFO9E6j6VAOEoIldm1kqdqRB210nAqRabVeIQOdHeArNLQje p7BHTlUYuOBYhkQauzohLPJF8bYi+z/jHlQz5WvStZJEzup+LpARXywxFWwJ5VbG5pry F43Mugeg+NMZdJ0baqrA/gLL2waL0t44Fu/EbxjixMl2SQVK1LVnD8Ith04Vf5XXmSKu PmOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680622372; 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=PDwFnbwAQ628E24lv/sil+v21rnO8HvTED6y6PCZ2dg=; b=m/LPyI/3b2W0ct8Br06SXiI0+APxDCt5Ml2exc23YwwPpkl4sjUo8rA6yvHJkKn0fp DgtV0TfR1p+DvSp1VupT3f9BAQHEff1w9uJrctrsZhHVtlWWiacmjtLk57Zb2kVl6wf5 0CF2Ocr6ed3HqmW8R85W/2sTaFP8USa+B6+9VqYo3yo56vLdC26FApjvYzb5socIHCsX z5+aZ4Mi8k3hwubxTN9xUoG83yHQhoJZ4uSwpO6gkn9ynhQUvnuGpkBJYO1A42bAYOQ0 AsEO1HZWWmdUMhpt6XoaK4Tnx1ceVhXcvDjqoxvcgagov/vNKOeibx6/sQ5B8W6mwjDF +Zgw== X-Gm-Message-State: AAQBX9d46zK8H8KYFJtFra9uyrRokDDrs2F228Mh7+SwRTUipS2Dhl+6 HtWf4kI8S5vgcFqx6nVSXZfijJUp6BCnjb+JlCk= X-Google-Smtp-Source: AKy350bEKRQH3qKBiTjmUTjW6K7/xzA0cY2C/2b3KnbA8GYue69mJ4eTJ1J7JNx5L2Sqo9ctQ3a4RA== X-Received: by 2002:aa7:950d:0:b0:62d:d045:392 with SMTP id b13-20020aa7950d000000b0062dd0450392mr2847156pfp.32.1680622372301; Tue, 04 Apr 2023 08:32:52 -0700 (PDT) Received: from fedlinux.. ([106.84.131.166]) by smtp.gmail.com with ESMTPSA id p11-20020a62ab0b000000b0059085684b54sm9231519pff.140.2023.04.04.08.32.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Apr 2023 08:32:51 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , hare@suse.de, Hanna Reitz , dmitry.fomichev@wdc.com, Julia Suvorova , Stefano Garzarella , damien.lemoal@opensource.wdc.com, Stefan Hajnoczi , Aarushi Mehta , Kevin Wolf , qemu-block@nongnu.org, Sam Li Subject: [PATCH v8 1/4] file-posix: add tracking of the zone write pointers Date: Tue, 4 Apr 2023 23:32:36 +0800 Message-Id: <20230404153239.32234-2-faithilikerun@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230404153239.32234-1-faithilikerun@gmail.com> References: <20230404153239.32234-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-bounces+qemu-devel=archiver.kernel.org@nongnu.org Since Linux doesn't have a user API to issue zone append operations to zoned devices from user space, the file-posix driver is modified to add zone append emulation using regular writes. To do this, the file-posix driver tracks the wp location of all zones of the device. It uses an array of uint64_t. The most significant bit of each wp location indicates if the zone type is conventional zones. The zones wp can be changed due to the following operations issued: - zone reset: change the wp to the start offset of that zone - zone finish: change to the end location of that zone - write to a zone - zone append Signed-off-by: Sam Li --- block/file-posix.c | 168 ++++++++++++++++++++++++++++++- include/block/block-common.h | 14 +++ include/block/block_int-common.h | 5 + 3 files changed, 184 insertions(+), 3 deletions(-) diff --git a/block/file-posix.c b/block/file-posix.c index 65efe5147e..bc58f7193b 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1324,6 +1324,88 @@ static int hdev_get_max_segments(int fd, struct stat *st) #endif } +#if defined(CONFIG_BLKZONED) +/* + * If the reset_all flag is true, then the wps of zone whose state is + * not readonly or offline should be all reset to the start sector. + * Else, take the real wp of the device. + */ +static int get_zones_wp(int fd, BlockZoneWps *wps, int64_t offset, + unsigned int nrz, bool reset_all) +{ + struct blk_zone *blkz; + size_t rep_size; + uint64_t sector = offset >> BDRV_SECTOR_BITS; + int ret, n = 0, i = 0; + 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, offset, errno); + return -errno; + } + + if (!rep->nr_zones) { + break; + } + + for (i = 0; i < rep->nr_zones; i++, n++) { + /* + * The wp tracking cares only about sequential writes required and + * sequential write preferred zones so that the wp can advance to + * the right location. + * Use the most significant bit of the wp location to indicate the + * zone type: 0 for SWR/SWP zones and 1 for conventional zones. + */ + if (blkz[i].type == BLK_ZONE_TYPE_CONVENTIONAL) { + wps->wp[i] &= 1ULL << 63; + } else { + switch(blkz[i].cond) { + case BLK_ZONE_COND_FULL: + case BLK_ZONE_COND_READONLY: + /* Zone not writable */ + wps->wp[i] = (blkz[i].start + blkz[i].len) << BDRV_SECTOR_BITS; + break; + case BLK_ZONE_COND_OFFLINE: + /* Zone not writable nor readable */ + wps->wp[i] = (blkz[i].start) << BDRV_SECTOR_BITS; + break; + default: + if (reset_all) { + wps->wp[i] = blkz[i].start << BDRV_SECTOR_BITS; + } else { + wps->wp[i] = blkz[i].wp << BDRV_SECTOR_BITS; + } + break; + } + } + } + sector = blkz[i - 1].start + blkz[i - 1].len; + } + + return 0; +} + +static void update_zones_wp(int fd, BlockZoneWps *wps, int64_t offset, + unsigned int nrz) +{ + if (get_zones_wp(fd, wps, offset, nrz, 0) < 0) { + error_report("update zone wp failed"); + } +} +#endif + static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVRawState *s = bs->opaque; @@ -1413,6 +1495,23 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) if (ret >= 0) { bs->bl.max_active_zones = ret; } + + ret = get_sysfs_long_val(&st, "physical_block_size"); + if (ret >= 0) { + bs->bl.write_granularity = ret; + } + + /* The refresh_limits() function can be called multiple times. */ + bs->wps = NULL; + bs->wps = g_malloc(sizeof(BlockZoneWps) + + sizeof(int64_t) * bs->bl.nr_zones); + ret = get_zones_wp(s->fd, bs->wps, 0, bs->bl.nr_zones, 0); + if (ret < 0) { + error_setg_errno(errp, -ret, "report wps failed"); + bs->wps = NULL; + return; + } + qemu_co_mutex_init(&bs->wps->colock); return; } out: @@ -2338,9 +2437,15 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, { BDRVRawState *s = bs->opaque; RawPosixAIOData acb; + int ret; if (fd_open(bs) < 0) return -EIO; +#if defined(CONFIG_BLKZONED) + if (type & QEMU_AIO_WRITE && bs->wps) { + QEMU_LOCK_GUARD(&bs->wps->colock); + } +#endif /* * When using O_DIRECT, the request must be aligned to be able to use @@ -2354,14 +2459,16 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, } else if (s->use_linux_io_uring) { LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs)); assert(qiov->size == bytes); - return luring_co_submit(bs, aio, s->fd, offset, qiov, type); + ret = luring_co_submit(bs, aio, s->fd, offset, qiov, type); + goto out; #endif #ifdef CONFIG_LINUX_AIO } else if (s->use_linux_aio) { LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs)); assert(qiov->size == bytes); - return laio_co_submit(bs, aio, s->fd, offset, qiov, type, + ret = laio_co_submit(bs, aio, s->fd, offset, qiov, type, s->aio_max_batch); + goto out; #endif } @@ -2378,7 +2485,29 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, }; assert(qiov->size == bytes); - return raw_thread_pool_submit(bs, handle_aiocb_rw, &acb); + ret = raw_thread_pool_submit(bs, handle_aiocb_rw, &acb); + +out: +#if defined(CONFIG_BLKZONED) + BlockZoneWps *wps = bs->wps; + if (ret == 0) { + if (type & QEMU_AIO_WRITE && wps && bs->bl.zone_size) { + uint64_t *wp = &wps->wp[offset / bs->bl.zone_size]; + if (!BDRV_ZT_IS_CONV(*wp)) { + /* Advance the wp if needed */ + if (offset + bytes > *wp) { + *wp = offset + bytes; + } + } + } + } else { + if (type & QEMU_AIO_WRITE) { + update_zones_wp(s->fd, bs->wps, 0, 1); + } + } + +#endif + return ret; } static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset, @@ -2486,6 +2615,9 @@ static void raw_close(BlockDriverState *bs) BDRVRawState *s = bs->opaque; if (s->fd >= 0) { +#if defined(CONFIG_BLKZONED) + g_free(bs->wps); +#endif qemu_close(s->fd); s->fd = -1; } @@ -3283,6 +3415,7 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, const char *op_name; unsigned long zo; int ret; + BlockZoneWps *wps = bs->wps; int64_t capacity = bs->total_sectors << BDRV_SECTOR_BITS; zone_size = bs->bl.zone_size; @@ -3300,6 +3433,15 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, return -EINVAL; } + QEMU_LOCK_GUARD(&wps->colock); + uint32_t i = offset / bs->bl.zone_size; + uint32_t nrz = len / bs->bl.zone_size; + uint64_t *wp = &wps->wp[i]; + if (BDRV_ZT_IS_CONV(*wp) && len != capacity) { + error_report("zone mgmt operations are not allowed for conventional zones"); + return -EIO; + } + switch (op) { case BLK_ZO_OPEN: op_name = "BLKOPENZONE"; @@ -3337,8 +3479,28 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, len >> BDRV_SECTOR_BITS); ret = raw_thread_pool_submit(bs, handle_aiocb_zone_mgmt, &acb); if (ret != 0) { + update_zones_wp(s->fd, wps, offset, i); ret = -errno; error_report("ioctl %s failed %d", op_name, ret); + return ret; + } + + if (zo == BLKRESETZONE && len == capacity) { + ret = get_zones_wp(s->fd, wps, 0, bs->bl.nr_zones, 1); + if (ret < 0) { + error_report("reporting single wp failed"); + return ret; + } + } else if (zo == BLKRESETZONE) { + for (int j = 0; j < nrz; ++j) { + wp[j] = offset + j * zone_size; + } + } else if (zo == BLKFINISHZONE) { + for (int j = 0; j < nrz; ++j) { + /* The zoned device allows the last zone smaller that the + * zone size. */ + wp[j] = MIN(offset + (j + 1) * zone_size, offset + len); + } } return ret; diff --git a/include/block/block-common.h b/include/block/block-common.h index 1576fcf2ed..93196229ac 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -118,6 +118,14 @@ typedef struct BlockZoneDescriptor { BlockZoneState state; } BlockZoneDescriptor; +/* + * Track write pointers of a zone in bytes. + */ +typedef struct BlockZoneWps { + CoMutex colock; + uint64_t wp[]; +} BlockZoneWps; + typedef struct BlockDriverInfo { /* in bytes, 0 if irrelevant */ int cluster_size; @@ -240,6 +248,12 @@ typedef enum { #define BDRV_SECTOR_BITS 9 #define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS) +/* + * Get the first most significant bit of wp. If it is zero, then + * the zone type is SWR. + */ +#define BDRV_ZT_IS_CONV(wp) (wp & (1ULL << 63)) + #define BDRV_REQUEST_MAX_SECTORS MIN_CONST(SIZE_MAX >> BDRV_SECTOR_BITS, \ INT_MAX >> BDRV_SECTOR_BITS) #define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS) diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 1bd2aef4d5..b34a7f175d 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -884,6 +884,8 @@ typedef struct BlockLimits { /* maximum number of active zones */ int64_t max_active_zones; + + int64_t write_granularity; } BlockLimits; typedef struct BdrvOpBlocker BdrvOpBlocker; @@ -1245,6 +1247,9 @@ struct BlockDriverState { CoMutex bsc_modify_lock; /* Always non-NULL, but must only be dereferenced under an RCU read guard */ BdrvBlockStatusCache *block_status_cache; + + /* array of write pointers' location of each zone in the zoned device. */ + BlockZoneWps *wps; }; struct BlockBackendRootState { From patchwork Tue Apr 4 15:32:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13200478 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 923ACC761A6 for ; Tue, 4 Apr 2023 15:34:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pjied-0004Xq-Gn; Tue, 04 Apr 2023 11:33:03 -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 1pjiec-0004XX-Sw; Tue, 04 Apr 2023 11:33:02 -0400 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pjiea-0005p8-LI; Tue, 04 Apr 2023 11:33:02 -0400 Received: by mail-pg1-x531.google.com with SMTP id 184so5245867pga.12; Tue, 04 Apr 2023 08:33:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680622378; 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=6RYKgL58o80fFY5ge3qanJNqaVJDShUY9fdciMlBYKo=; b=Spt9OpWkG6U/SaN1w3+plnivDJ1i/mXNAvydpA48D5MTR49c9NxE/T6/XYS3BSFGbZ xbCmkTiDnWVzneW13nl5V7LTrAs08RDVNnfsWxk4LGTlSOO1HJ+ay4+X2hrmpfto+q25 q3cUl2y2SH9JtXgfvO5smzHHXmDCKo1sdr511rqZSrV1wQZE/22MDb4mnVC9eafYPcSA dY73TVvSc9VbYDWMIUPI2cZvwNX8S1EM3VBNyfvBKqq0Sjntr/yTZaWjAyOBO71eMuQd bdFiFkkrSnbZSCYkkzqQS1gpCTo5Nn2xo6bueAJn03zHQr24GexUS69d4qrCqz6/8EhD bf1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680622378; 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=6RYKgL58o80fFY5ge3qanJNqaVJDShUY9fdciMlBYKo=; b=Fa+FcCDG43GIa4cD+z7VA/nGbTqT9l8jkLRxsEYDid+PxuDbXcW8xnkT2hdOXJutvo tAKmxYU0xBK8mcmz1JL9yHiMIp1UVSCWdhNujb4aLc858Ik44pMofgoQ2R5OpiHit+wU Cli/yjZbmGp3n+nryEO37vUhvbvDEFctgTZUsn9TtRn5dGH13yNwmQVid8m7N8zClg9O QN+Tc6JR+9+vgczp++ZrxJxRsaQxW5r1dvALCnANRfOw1x6K2cw6yl9mMG+CgA4Fql2j 7tisVVfZW0EaJMRbzJVZr1XaXquPR9dK9V57OlOziw6QZnE/ke7ZgkJbvJ/cJOoui45p JMsA== X-Gm-Message-State: AAQBX9cOwL7XwrxmfexVwRnTFKj8Zwkf9ig3lkMmtNQodWFSojcP7d3m 0a8WO66ynkUHsf/K0nK9S5u+2ejNLd+5G9yO9nM= X-Google-Smtp-Source: AKy350YwrxaPknNqdh+YJMASKsvW0cMHtW579ePeStTu7o7/HQ/aA1yrjqgNVy6x9qM2/VVJmgan0g== X-Received: by 2002:aa7:8f24:0:b0:62d:e5eb:2d73 with SMTP id y4-20020aa78f24000000b0062de5eb2d73mr2693828pfr.34.1680622378085; Tue, 04 Apr 2023 08:32:58 -0700 (PDT) Received: from fedlinux.. ([106.84.131.166]) by smtp.gmail.com with ESMTPSA id p11-20020a62ab0b000000b0059085684b54sm9231519pff.140.2023.04.04.08.32.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Apr 2023 08:32:57 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , hare@suse.de, Hanna Reitz , dmitry.fomichev@wdc.com, Julia Suvorova , Stefano Garzarella , damien.lemoal@opensource.wdc.com, Stefan Hajnoczi , Aarushi Mehta , Kevin Wolf , qemu-block@nongnu.org, Sam Li Subject: [PATCH v8 2/4] block: introduce zone append write for zoned devices Date: Tue, 4 Apr 2023 23:32:37 +0800 Message-Id: <20230404153239.32234-3-faithilikerun@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230404153239.32234-1-faithilikerun@gmail.com> References: <20230404153239.32234-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x531.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-bounces+qemu-devel=archiver.kernel.org@nongnu.org A zone append command is a write operation that specifies the first logical block of a zone as the write position. When writing to a zoned block device using zone append, the byte offset of the call may point at any position within the zone to which the data is being appended. Upon completion the device will respond with the position where the data has been written in the zone. Signed-off-by: Sam Li Reviewed-by: Dmitry Fomichev Reviewed-by: Stefan Hajnoczi --- block/block-backend.c | 60 +++++++++++++++++++++++++++++++ block/file-posix.c | 56 +++++++++++++++++++++++++---- block/io.c | 27 ++++++++++++++ block/io_uring.c | 4 +++ block/linux-aio.c | 3 ++ block/raw-format.c | 8 +++++ include/block/block-io.h | 4 +++ include/block/block_int-common.h | 3 ++ include/block/raw-aio.h | 4 ++- include/sysemu/block-backend-io.h | 9 +++++ 10 files changed, 171 insertions(+), 7 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index f70b08e3f6..bcb3a1eff0 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1888,6 +1888,45 @@ BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op, return &acb->common; } +static void coroutine_fn blk_aio_zone_append_entry(void *opaque) +{ + BlkAioEmAIOCB *acb = opaque; + BlkRwCo *rwco = &acb->rwco; + + rwco->ret = blk_co_zone_append(rwco->blk, (int64_t *)acb->bytes, + rwco->iobuf, rwco->flags); + blk_aio_complete(acb); +} + +BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset, + QEMUIOVector *qiov, BdrvRequestFlags flags, + 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, + .ret = NOT_DONE, + .flags = flags, + .iobuf = qiov, + }; + acb->bytes = (int64_t)offset; + acb->has_returned = false; + + co = qemu_coroutine_create(blk_aio_zone_append_entry, acb); + aio_co_enter(blk_get_aio_context(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 @@ -1939,6 +1978,27 @@ int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op, return ret; } +/* + * Send a zone_append command. + */ +int coroutine_fn blk_co_zone_append(BlockBackend *blk, int64_t *offset, + QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + int ret; + IO_CODE(); + + blk_inc_in_flight(blk); + blk_wait_while_drained(blk); + if (!blk_is_available(blk)) { + blk_dec_in_flight(blk); + return -ENOMEDIUM; + } + + ret = bdrv_co_zone_append(blk_bs(blk), offset, qiov, flags); + 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 bc58f7193b..a7130b1024 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -160,6 +160,7 @@ typedef struct BDRVRawState { bool has_write_zeroes:1; bool use_linux_aio:1; bool use_linux_io_uring:1; + int64_t *offset; /* offset of zone append operation */ int page_cache_inconsistent; /* errno from fdatasync failure */ bool has_fallocate; bool needs_alignment; @@ -1685,7 +1686,7 @@ static ssize_t handle_aiocb_rw_vector(RawPosixAIOData *aiocb) ssize_t len; len = RETRY_ON_EINTR( - (aiocb->aio_type & QEMU_AIO_WRITE) ? + (aiocb->aio_type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) ? qemu_pwritev(aiocb->aio_fildes, aiocb->io.iov, aiocb->io.niov, @@ -1714,7 +1715,7 @@ static ssize_t handle_aiocb_rw_linear(RawPosixAIOData *aiocb, char *buf) ssize_t len; while (offset < aiocb->aio_nbytes) { - if (aiocb->aio_type & QEMU_AIO_WRITE) { + if (aiocb->aio_type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) { len = pwrite(aiocb->aio_fildes, (const char *)buf + offset, aiocb->aio_nbytes - offset, @@ -1807,7 +1808,7 @@ static int handle_aiocb_rw(void *opaque) } nbytes = handle_aiocb_rw_linear(aiocb, buf); - if (!(aiocb->aio_type & QEMU_AIO_WRITE)) { + if (!(aiocb->aio_type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND))) { char *p = buf; size_t count = aiocb->aio_nbytes, copy; int i; @@ -2442,8 +2443,12 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, if (fd_open(bs) < 0) return -EIO; #if defined(CONFIG_BLKZONED) - if (type & QEMU_AIO_WRITE && bs->wps) { + if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) && bs->wps) { QEMU_LOCK_GUARD(&bs->wps->colock); + if (type & QEMU_AIO_ZONE_APPEND && bs->bl.zone_size) { + int index = offset / bs->bl.zone_size; + offset = bs->wps->wp[index]; + } } #endif @@ -2491,9 +2496,13 @@ out: #if defined(CONFIG_BLKZONED) BlockZoneWps *wps = bs->wps; if (ret == 0) { - if (type & QEMU_AIO_WRITE && wps && bs->bl.zone_size) { + if ((type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) + && wps && bs->bl.zone_size) { uint64_t *wp = &wps->wp[offset / bs->bl.zone_size]; if (!BDRV_ZT_IS_CONV(*wp)) { + if (type & QEMU_AIO_ZONE_APPEND) { + *s->offset = *wp; + } /* Advance the wp if needed */ if (offset + bytes > *wp) { *wp = offset + bytes; @@ -2501,7 +2510,7 @@ out: } } } else { - if (type & QEMU_AIO_WRITE) { + if (type & (QEMU_AIO_WRITE | QEMU_AIO_ZONE_APPEND)) { update_zones_wp(s->fd, bs->wps, 0, 1); } } @@ -3507,6 +3516,40 @@ static int coroutine_fn raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, } #endif +#if defined(CONFIG_BLKZONED) +static int coroutine_fn raw_co_zone_append(BlockDriverState *bs, + int64_t *offset, + QEMUIOVector *qiov, + BdrvRequestFlags flags) { + assert(flags == 0); + int64_t zone_size_mask = bs->bl.zone_size - 1; + int64_t iov_len = 0; + int64_t len = 0; + BDRVRawState *s = bs->opaque; + s->offset = offset; + + if (*offset & zone_size_mask) { + error_report("sector offset %" PRId64 " is not aligned to zone size " + "%" PRId32 "", *offset / 512, bs->bl.zone_size / 512); + return -EINVAL; + } + + int64_t wg = bs->bl.write_granularity; + int64_t wg_mask = wg - 1; + for (int i = 0; i < qiov->niov; i++) { + iov_len = qiov->iov[i].iov_len; + if (iov_len & wg_mask) { + error_report("len of IOVector[%d] %" PRId64 " is not aligned to " + "block size %" PRId64 "", i, iov_len, wg); + return -EINVAL; + } + len += iov_len; + } + + return raw_co_prw(bs, *offset, len, qiov, QEMU_AIO_ZONE_APPEND); +} +#endif + static coroutine_fn int raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes, bool blkdev) @@ -4268,6 +4311,7 @@ static BlockDriver bdrv_host_device = { /* zone management operations */ .bdrv_co_zone_report = raw_co_zone_report, .bdrv_co_zone_mgmt = raw_co_zone_mgmt, + .bdrv_co_zone_append = raw_co_zone_append, #endif }; diff --git a/block/io.c b/block/io.c index 5dbf1e50f2..3186faa278 100644 --- a/block/io.c +++ b/block/io.c @@ -3152,6 +3152,33 @@ out: return co.ret; } +int coroutine_fn bdrv_co_zone_append(BlockDriverState *bs, int64_t *offset, + QEMUIOVector *qiov, + BdrvRequestFlags flags) +{ + int ret; + BlockDriver *drv = bs->drv; + CoroutineIOCompletion co = { + .coroutine = qemu_coroutine_self(), + }; + IO_CODE(); + + ret = bdrv_check_qiov_request(*offset, qiov->size, qiov, 0, NULL); + if (ret < 0) { + return ret; + } + + bdrv_inc_in_flight(bs); + if (!drv || !drv->bdrv_co_zone_append || bs->bl.zoned == BLK_Z_NONE) { + co.ret = -ENOTSUP; + goto out; + } + co.ret = drv->bdrv_co_zone_append(bs, offset, qiov, flags); +out: + bdrv_dec_in_flight(bs); + return co.ret; +} + void *qemu_blockalign(BlockDriverState *bs, size_t size) { IO_CODE(); diff --git a/block/io_uring.c b/block/io_uring.c index 973e15d876..f7488c241a 100644 --- a/block/io_uring.c +++ b/block/io_uring.c @@ -345,6 +345,10 @@ static int luring_do_submit(int fd, LuringAIOCB *luringcb, LuringState *s, io_uring_prep_writev(sqes, fd, luringcb->qiov->iov, luringcb->qiov->niov, offset); break; + case QEMU_AIO_ZONE_APPEND: + io_uring_prep_writev(sqes, fd, luringcb->qiov->iov, + luringcb->qiov->niov, offset); + break; case QEMU_AIO_READ: io_uring_prep_readv(sqes, fd, luringcb->qiov->iov, luringcb->qiov->niov, offset); diff --git a/block/linux-aio.c b/block/linux-aio.c index d2cfb7f523..1959834156 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -389,6 +389,9 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset, case QEMU_AIO_WRITE: io_prep_pwritev(iocbs, fd, qiov->iov, qiov->niov, offset); break; + case QEMU_AIO_ZONE_APPEND: + io_prep_pwritev(iocbs, fd, qiov->iov, qiov->niov, offset); + break; case QEMU_AIO_READ: io_prep_preadv(iocbs, fd, qiov->iov, qiov->niov, offset); break; diff --git a/block/raw-format.c b/block/raw-format.c index 72e23e7b55..64e7d48d04 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -332,6 +332,13 @@ raw_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, return bdrv_co_zone_mgmt(bs->file->bs, op, offset, len); } +static int coroutine_fn GRAPH_RDLOCK +raw_co_zone_append(BlockDriverState *bs,int64_t *offset, QEMUIOVector *qiov, + BdrvRequestFlags flags) +{ + return bdrv_co_zone_append(bs->file->bs, offset, qiov, flags); +} + static int64_t coroutine_fn GRAPH_RDLOCK raw_co_getlength(BlockDriverState *bs) { @@ -635,6 +642,7 @@ BlockDriver bdrv_raw = { .bdrv_co_pdiscard = &raw_co_pdiscard, .bdrv_co_zone_report = &raw_co_zone_report, .bdrv_co_zone_mgmt = &raw_co_zone_mgmt, + .bdrv_co_zone_append = &raw_co_zone_append, .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, diff --git a/include/block/block-io.h b/include/block/block-io.h index 19d1fad9cf..55fca02991 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -120,6 +120,10 @@ int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_report(BlockDriverState *bs, int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op, int64_t offset, int64_t len); +int coroutine_fn GRAPH_RDLOCK bdrv_co_zone_append(BlockDriverState *bs, + int64_t *offset, + QEMUIOVector *qiov, + BdrvRequestFlags flags); 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 b34a7f175d..efa5a8e967 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -724,6 +724,9 @@ struct BlockDriver { BlockZoneDescriptor *zones); int coroutine_fn (*bdrv_co_zone_mgmt)(BlockDriverState *bs, BlockZoneOp op, int64_t offset, int64_t len); + int coroutine_fn (*bdrv_co_zone_append)(BlockDriverState *bs, + int64_t *offset, QEMUIOVector *qiov, + BdrvRequestFlags flags); /* removable device specific */ bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)( diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h index eda6a7a253..fb9c9f5a01 100644 --- a/include/block/raw-aio.h +++ b/include/block/raw-aio.h @@ -30,6 +30,7 @@ #define QEMU_AIO_TRUNCATE 0x0080 #define QEMU_AIO_ZONE_REPORT 0x0100 #define QEMU_AIO_ZONE_MGMT 0x0200 +#define QEMU_AIO_ZONE_APPEND 0x0400 #define QEMU_AIO_TYPE_MASK \ (QEMU_AIO_READ | \ QEMU_AIO_WRITE | \ @@ -40,7 +41,8 @@ QEMU_AIO_COPY_RANGE | \ QEMU_AIO_TRUNCATE | \ QEMU_AIO_ZONE_REPORT | \ - QEMU_AIO_ZONE_MGMT) + QEMU_AIO_ZONE_MGMT | \ + QEMU_AIO_ZONE_APPEND) /* AIO flags */ #define QEMU_AIO_MISALIGNED 0x1000 diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h index f575ab5b6b..e716591a1a 100644 --- a/include/sysemu/block-backend-io.h +++ b/include/sysemu/block-backend-io.h @@ -53,6 +53,9 @@ BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset, BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op, int64_t offset, int64_t len, BlockCompletionFunc *cb, void *opaque); +BlockAIOCB *blk_aio_zone_append(BlockBackend *blk, int64_t *offset, + QEMUIOVector *qiov, BdrvRequestFlags flags, + 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); @@ -201,6 +204,12 @@ int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op, int64_t offset, int64_t len); int co_wrapper_mixed blk_zone_mgmt(BlockBackend *blk, BlockZoneOp op, int64_t offset, int64_t len); +int coroutine_fn blk_co_zone_append(BlockBackend *blk, int64_t *offset, + QEMUIOVector *qiov, + BdrvRequestFlags flags); +int co_wrapper_mixed blk_zone_append(BlockBackend *blk, int64_t *offset, + QEMUIOVector *qiov, + BdrvRequestFlags flags); int co_wrapper_mixed blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes); From patchwork Tue Apr 4 15:32:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13200480 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 8B872C761A6 for ; Tue, 4 Apr 2023 15:34:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pjiei-0004a5-En; Tue, 04 Apr 2023 11:33:08 -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 1pjieh-0004ZV-0z; Tue, 04 Apr 2023 11:33:07 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pjiee-0005t2-R2; Tue, 04 Apr 2023 11:33:06 -0400 Received: by mail-pj1-x102d.google.com with SMTP id mp3-20020a17090b190300b0023fcc8ce113so36519718pjb.4; Tue, 04 Apr 2023 08:33:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680622382; 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=hMgWCguzRYpDVHAJaMrHcwUlCI7lXgwjUP1BNHLpMtU=; b=RU8zl4etVDeZbc7ImsXvg3jxIqnnyFWS1cHKBALy9c6He/uyhzitEdRYR7WAJ08c6b ZH+hHHRi4qsR4brbA+j1KDDNVJ9Bxt/kYaU3xdRGdFJuImSE9UbUR3x4I3il68oaAlQj q3foJQM+Yn8djUhgvGsnyRfK9/b+kA6pBl9f1K51QWoMDdaOhfbP3eIEbFrmMWBJj8cD HTIX+qJRtjxA6iKRW7RIYNK6mGkM07ZTjDpfEPV/WLlOR5aJTlO9Mn1w2NWm1OEfP+lH ZpZeE7KYBxM3LYXqY3sMqzyzm7CigPF3rzWKIshqXsYZMJqGnrmvXGss8HycurgnQFc3 kZig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680622382; 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=hMgWCguzRYpDVHAJaMrHcwUlCI7lXgwjUP1BNHLpMtU=; b=wcDaZcg1IPGPojTx/PBlbKXkA1djsYSSeXAcFo3NT+15I0Ug2krb0A6oehUcIVdeKR fYBZoL8VsF2kxI7eZhjEu7gd4klszlyNPU9tohwah+4Sr04/u2Q+WwQbnsbahrA0JqFY mUVSoj+KO0notHTNECWXOBKF+8QC9mFumSi0jaFrNHopgVteETx2hqP6xchcP7+bFA5g BotMMTyId2aqOn1d+p77nxn2g+/YjxuuYn1m+Ksini4dc0hJY4uMfrAJFjTHvIxttx6Z Zlc2wTX2ewOM0KN+ycNaK5GcS4X9ygYYSATQF6q72FHTNk4MDB0xsNW9XzN3EMli/LhD JSwQ== X-Gm-Message-State: AAQBX9ecwdoxwxybPa3T3HB4Yithqe1K21KUdqhjGhEiU5sY1UvLJXWL WzbapPPXT6Uq11ZUO/LT6TvKhMNLW1EUvFza/EQ= X-Google-Smtp-Source: AKy350Zjwr0sRMQRilkhUVO+xmo5L+LuIQd1OZZGcSW43wyW7foXfNbLwjUHYcWXu+qLT8on7wgY8g== X-Received: by 2002:a05:6a20:1221:b0:db:443b:58d0 with SMTP id v33-20020a056a20122100b000db443b58d0mr2296234pzf.12.1680622382610; Tue, 04 Apr 2023 08:33:02 -0700 (PDT) Received: from fedlinux.. ([106.84.131.166]) by smtp.gmail.com with ESMTPSA id p11-20020a62ab0b000000b0059085684b54sm9231519pff.140.2023.04.04.08.32.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Apr 2023 08:33:02 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , hare@suse.de, Hanna Reitz , dmitry.fomichev@wdc.com, Julia Suvorova , Stefano Garzarella , damien.lemoal@opensource.wdc.com, Stefan Hajnoczi , Aarushi Mehta , Kevin Wolf , qemu-block@nongnu.org, Sam Li Subject: [PATCH v8 3/4] qemu-iotests: test zone append operation Date: Tue, 4 Apr 2023 23:32:38 +0800 Message-Id: <20230404153239.32234-4-faithilikerun@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230404153239.32234-1-faithilikerun@gmail.com> References: <20230404153239.32234-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=faithilikerun@gmail.com; helo=mail-pj1-x102d.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-bounces+qemu-devel=archiver.kernel.org@nongnu.org The patch tests zone append writes by reporting the zone wp after the completion of the call. "zap -p" option can print the sector offset value after completion, which should be the start sector where the append write begins. Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi --- qemu-io-cmds.c | 75 ++++++++++++++++++++++++++++++ tests/qemu-iotests/tests/zoned | 16 +++++++ tests/qemu-iotests/tests/zoned.out | 16 +++++++ 3 files changed, 107 insertions(+) diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index f35ea627d7..3f75d2f5a6 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1874,6 +1874,80 @@ static const cmdinfo_t zone_reset_cmd = { .oneline = "reset a zone write pointer in zone block device", }; +static int do_aio_zone_append(BlockBackend *blk, QEMUIOVector *qiov, + int64_t *offset, int flags, int *total) +{ + int async_ret = NOT_DONE; + + blk_aio_zone_append(blk, offset, qiov, flags, aio_rw_done, &async_ret); + while (async_ret == NOT_DONE) { + main_loop_wait(false); + } + + *total = qiov->size; + return async_ret < 0 ? async_ret : 1; +} + +static int zone_append_f(BlockBackend *blk, int argc, char **argv) +{ + int ret; + bool pflag = false; + int flags = 0; + int total = 0; + int64_t offset; + char *buf; + int c, nr_iov; + int pattern = 0xcd; + QEMUIOVector qiov; + + if (optind > argc - 3) { + return -EINVAL; + } + + if ((c = getopt(argc, argv, "p")) != -1) { + pflag = true; + } + + offset = cvtnum(argv[optind]); + if (offset < 0) { + print_cvtnum_err(offset, argv[optind]); + return offset; + } + optind++; + nr_iov = argc - optind; + buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern, + flags & BDRV_REQ_REGISTERED_BUF); + if (buf == NULL) { + return -EINVAL; + } + ret = do_aio_zone_append(blk, &qiov, &offset, flags, &total); + if (ret < 0) { + printf("zone append failed: %s\n", strerror(-ret)); + goto out; + } + + if (pflag) { + printf("After zap done, the append sector is 0x%" PRIx64 "\n", + tosector(offset)); + } + +out: + qemu_io_free(blk, buf, qiov.size, + flags & BDRV_REQ_REGISTERED_BUF); + qemu_iovec_destroy(&qiov); + return ret; +} + +static const cmdinfo_t zone_append_cmd = { + .name = "zone_append", + .altname = "zap", + .cfunc = zone_append_f, + .argmin = 3, + .argmax = 4, + .args = "offset len [len..]", + .oneline = "append write a number of bytes at a specified offset", +}; + static int truncate_f(BlockBackend *blk, int argc, char **argv); static const cmdinfo_t truncate_cmd = { .name = "truncate", @@ -2672,6 +2746,7 @@ static void __attribute((constructor)) init_qemuio_commands(void) qemuio_add_command(&zone_close_cmd); qemuio_add_command(&zone_finish_cmd); qemuio_add_command(&zone_reset_cmd); + qemuio_add_command(&zone_append_cmd); qemuio_add_command(&truncate_cmd); qemuio_add_command(&length_cmd); qemuio_add_command(&info_cmd); diff --git a/tests/qemu-iotests/tests/zoned b/tests/qemu-iotests/tests/zoned index 56f60616b5..3d23ce9cc1 100755 --- a/tests/qemu-iotests/tests/zoned +++ b/tests/qemu-iotests/tests/zoned @@ -82,6 +82,22 @@ echo "(5) resetting the second zone" $QEMU_IO $IMG -c "zrs 268435456 268435456" echo "After resetting a zone:" $QEMU_IO $IMG -c "zrp 268435456 1" +echo +echo +echo "(6) append write" # the physical block size of the device is 4096 +$QEMU_IO $IMG -c "zrp 0 1" +$QEMU_IO $IMG -c "zap -p 0 0x1000 0x2000" +echo "After appending the first zone firstly:" +$QEMU_IO $IMG -c "zrp 0 1" +$QEMU_IO $IMG -c "zap -p 0 0x1000 0x2000" +echo "After appending the first zone secondly:" +$QEMU_IO $IMG -c "zrp 0 1" +$QEMU_IO $IMG -c "zap -p 268435456 0x1000 0x2000" +echo "After appending the second zone firstly:" +$QEMU_IO $IMG -c "zrp 268435456 1" +$QEMU_IO $IMG -c "zap -p 268435456 0x1000 0x2000" +echo "After appending the second zone secondly:" +$QEMU_IO $IMG -c "zrp 268435456 1" # success, all done echo "*** done" diff --git a/tests/qemu-iotests/tests/zoned.out b/tests/qemu-iotests/tests/zoned.out index b2d061da49..fe53ba4744 100644 --- a/tests/qemu-iotests/tests/zoned.out +++ b/tests/qemu-iotests/tests/zoned.out @@ -50,4 +50,20 @@ 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] + + +(6) append write +start: 0x0, len 0x80000, cap 0x80000, wptr 0x0, zcond:1, [type: 2] +After zap done, the append sector is 0x0 +After appending the first zone firstly: +start: 0x0, len 0x80000, cap 0x80000, wptr 0x18, zcond:2, [type: 2] +After zap done, the append sector is 0x18 +After appending the first zone secondly: +start: 0x0, len 0x80000, cap 0x80000, wptr 0x30, zcond:2, [type: 2] +After zap done, the append sector is 0x80000 +After appending the second zone firstly: +start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80018, zcond:2, [type: 2] +After zap done, the append sector is 0x80018 +After appending the second zone secondly: +start: 0x80000, len 0x80000, cap 0x80000, wptr 0x80030, zcond:2, [type: 2] *** done From patchwork Tue Apr 4 15:32:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13200477 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 15FE7C761A6 for ; Tue, 4 Apr 2023 15:34:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pjiem-0004cl-SW; Tue, 04 Apr 2023 11:33:12 -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 1pjiel-0004bI-FC; Tue, 04 Apr 2023 11:33:11 -0400 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pjiej-0006Ag-Nb; Tue, 04 Apr 2023 11:33:11 -0400 Received: by mail-pg1-x531.google.com with SMTP id s19so19911885pgi.0; Tue, 04 Apr 2023 08:33:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680622388; 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=uIUl4aibgYpMUzkAkax39ZDiJuLd9+zXASXmdChjI9U=; b=Ophiuqt/ZzQ8SMrVWEuYuxilO9A/E9bmSwlC/0peLIra3durd/vkAZ0+K74QCoJ6yX ep2+xi0JQoteolldR/aLQSaovbdggUwScBdPPt0uLyp9uOVlplCPsDnHUqYeVDhosOK/ TyxbFsbXHc6BEOfs3M/ckwJfJAO1KxTlIvOt7TVKhznjEZ0SKv+I8FlNyOhVxyPvqj+v i1CLmAQi6RCPVbPEQ5KdMzKPryLyrti4oMUzXUR4nYHtA14wUr5gFX5QErkx6WUjzzqQ 5+PxAxvE7rc2XqmFTLFEayqVB5oJRfFlmPaGWqQZdimShKOjUdguUW5lw9b980+kYGtF ylNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680622388; 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=uIUl4aibgYpMUzkAkax39ZDiJuLd9+zXASXmdChjI9U=; b=cjuaICjyDHuqwHRl2EN3TmywuP+7YI0el3StY57uTyPcBIp6p4I6FkCtOoQXhAXV16 VP+b+TYtGm++sK5swX5U8KIhu0hMBn2VMezLEGEdSTT90H1FUdkJ1IJk1YmZfRBIfDaE NBCW9L52RTlBy0Ry1ETPc/CHhHPL2ScbAQN9mWDrDAFgoFG4MIGbcTspKOujYExQxoHz 36/fb/6xgfjH7Jr41wJEru3WmMtDBnrwWdVd43zcJut3ZexUx4b4R4xI83oR/BeSSPs/ TQl5/ox6sjjlsy2u8fkLT2JXLRTXiWpR4fuwN/P5hBvCCaN4UZowLgI4XlJmGMCtGtyj xZ1g== X-Gm-Message-State: AAQBX9fhWo6i0w5NYUe2MtQYNzDohoxsjZKEfNZIPEzY1wMZOITDB8su 7nIUaBz4dZ2e39ly9GOkOMtqLa9m/eIIXN+3loE= X-Google-Smtp-Source: AKy350ZkFQGgRrBJTtdPY0vsKdeol+znGMP085cE8xd4TABj2ArSbvIO2IenLJmXUNOTAh1lGKQhsw== X-Received: by 2002:a62:3847:0:b0:626:a9b:94b8 with SMTP id f68-20020a623847000000b006260a9b94b8mr2515425pfa.20.1680622387516; Tue, 04 Apr 2023 08:33:07 -0700 (PDT) Received: from fedlinux.. ([106.84.131.166]) by smtp.gmail.com with ESMTPSA id p11-20020a62ab0b000000b0059085684b54sm9231519pff.140.2023.04.04.08.33.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Apr 2023 08:33:06 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Fam Zheng , hare@suse.de, Hanna Reitz , dmitry.fomichev@wdc.com, Julia Suvorova , Stefano Garzarella , damien.lemoal@opensource.wdc.com, Stefan Hajnoczi , Aarushi Mehta , Kevin Wolf , qemu-block@nongnu.org, Sam Li Subject: [PATCH v8 4/4] block: add some trace events for zone append Date: Tue, 4 Apr 2023 23:32:39 +0800 Message-Id: <20230404153239.32234-5-faithilikerun@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230404153239.32234-1-faithilikerun@gmail.com> References: <20230404153239.32234-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=faithilikerun@gmail.com; helo=mail-pg1-x531.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-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Sam Li Reviewed-by: Dmitry Fomichev 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 a7130b1024..825301467e 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2502,6 +2502,8 @@ out: if (!BDRV_ZT_IS_CONV(*wp)) { if (type & QEMU_AIO_ZONE_APPEND) { *s->offset = *wp; + trace_zbd_zone_append_complete(bs, *s->offset + >> BDRV_SECTOR_BITS); } /* Advance the wp if needed */ if (offset + bytes > *wp) { @@ -3546,6 +3548,7 @@ static int coroutine_fn raw_co_zone_append(BlockDriverState *bs, len += iov_len; } + trace_zbd_zone_append(bs, *offset >> BDRV_SECTOR_BITS); return raw_co_prw(bs, *offset, len, qiov, QEMU_AIO_ZONE_APPEND); } #endif diff --git a/block/trace-events b/block/trace-events index 3f4e1d088a..32665158d6 100644 --- a/block/trace-events +++ b/block/trace-events @@ -211,6 +211,8 @@ 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" +zbd_zone_append(void *bs, int64_t sector) "bs %p append at sector offset 0x%" PRIx64 "" +zbd_zone_append_complete(void *bs, int64_t sector) "bs %p returns append sector 0x%" PRIx64 "" # 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)"