From: Su Yue <l@damenly.su>
To: Naohiro Aota <naohiro.aota@wdc.com>
Cc: David Sterba <dsterba@suse.com>,
linux-btrfs@vger.kernel.org, Josef Bacik <josef@toxicpanda.com>
Subject: Re: [PATCH 05/26] btrfs-progs: zoned: get zone information of zoned block devices
Date: Mon, 26 Apr 2021 15:32:23 +0800 [thread overview]
Message-ID: <bla1pkg4.fsf@damenly.su> (raw)
In-Reply-To: <0c6581b81ebb7bc573c6c6c533c134b34b294dca.1619416549.git.naohiro.aota@wdc.com>
On Mon 26 Apr 2021 at 14:27, Naohiro Aota <naohiro.aota@wdc.com>
wrote:
> Get the zone information (number of zones and zone size) from
> all the
> devices, if the volume contains a zoned block device. To avoid
> costly
> run-time zone report commands to test the device zones type
> during block
> allocation, it also records all the zone status (zone type,
> write pointer
> position, etc.).
>
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
> ---
> Makefile | 2 +-
> common/device-scan.c | 2 +
> kerncompat.h | 4 +
> kernel-shared/disk-io.c | 12 ++
> kernel-shared/volumes.c | 2 +
> kernel-shared/volumes.h | 2 +
> kernel-shared/zoned.c | 242
> ++++++++++++++++++++++++++++++++++++++++
> kernel-shared/zoned.h | 42 +++++++
> 8 files changed, 307 insertions(+), 1 deletion(-)
> create mode 100644 kernel-shared/zoned.c
> create mode 100644 kernel-shared/zoned.h
>
> diff --git a/Makefile b/Makefile
> index e288a336c81e..3dc0543982b2 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -169,7 +169,7 @@ libbtrfs_objects = common/send-stream.o
> common/send-utils.o kernel-lib/rbtree.o
> kernel-shared/free-space-cache.o
> kernel-shared/root-tree.o \
> kernel-shared/volumes.o kernel-shared/transaction.o \
> kernel-shared/free-space-tree.o repair.o
> kernel-shared/inode-item.o \
> - kernel-shared/file-item.o \
> + kernel-shared/file-item.o kernel-shared/zoned.o \
> kernel-lib/raid56.o kernel-lib/tables.o \
> common/device-scan.o common/path-utils.o \
> common/utils.o libbtrfsutil/subvolume.o
> libbtrfsutil/stubs.o \
> diff --git a/common/device-scan.c b/common/device-scan.c
> index 01d2e0656583..74d7853afccb 100644
> --- a/common/device-scan.c
> +++ b/common/device-scan.c
> @@ -35,6 +35,7 @@
> #include "kernel-shared/ctree.h"
> #include "kernel-shared/volumes.h"
> #include "kernel-shared/disk-io.h"
> +#include "kernel-shared/zoned.h"
> #include "ioctl.h"
>
> static int btrfs_scan_done = 0;
> @@ -198,6 +199,7 @@ int btrfs_add_to_fsid(struct
> btrfs_trans_handle *trans,
> return 0;
>
> out:
> + free(device->zone_info);
> free(device);
> free(buf);
> return ret;
> diff --git a/kerncompat.h b/kerncompat.h
> index 7060326fe4f4..a39b79cba767 100644
> --- a/kerncompat.h
> +++ b/kerncompat.h
> @@ -76,6 +76,10 @@
> #define ULONG_MAX (~0UL)
> #endif
>
> +#ifndef SECTOR_SHIFT
> +#define SECTOR_SHIFT 9
> +#endif
> +
> #define __token_glue(a,b,c) ___token_glue(a,b,c)
> #define ___token_glue(a,b,c) a ## b ## c
> #ifdef DEBUG_BUILD_CHECKS
> diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
> index a78be1e7a692..0519cb2358b5 100644
> --- a/kernel-shared/disk-io.c
> +++ b/kernel-shared/disk-io.c
> @@ -29,6 +29,7 @@
> #include "kernel-shared/disk-io.h"
> #include "kernel-shared/volumes.h"
> #include "kernel-shared/transaction.h"
> +#include "zoned.h"
> #include "crypto/crc32c.h"
> #include "common/utils.h"
> #include "kernel-shared/print-tree.h"
> @@ -1314,6 +1315,17 @@ static struct btrfs_fs_info
> *__open_ctree_fd(int fp, const char *path,
> if (!fs_info->chunk_root)
> return fs_info;
>
> + /*
> + * Get zone type information of zoned block devices. This will
> also
> + * handle emulation of a zoned filesystem if a regular device
> has the
> + * zoned incompat feature flag set.
> + */
> + ret = btrfs_get_dev_zone_info_all_devices(fs_info);
> + if (ret) {
> + error("zoned: failed to read device zone info: %d", ret);
> + goto out_chunk;
> + }
> +
> eb = fs_info->chunk_root->node;
> read_extent_buffer(eb, fs_info->chunk_tree_uuid,
> btrfs_header_chunk_tree_uuid(eb),
> diff --git a/kernel-shared/volumes.c b/kernel-shared/volumes.c
> index cbcf7bfa371d..63530a99b41c 100644
> --- a/kernel-shared/volumes.c
> +++ b/kernel-shared/volumes.c
> @@ -27,6 +27,7 @@
> #include "kernel-shared/transaction.h"
> #include "kernel-shared/print-tree.h"
> #include "kernel-shared/volumes.h"
> +#include "zoned.h"
> #include "common/utils.h"
> #include "kernel-lib/raid56.h"
>
> @@ -357,6 +358,7 @@ again:
> /* free the memory */
> free(device->name);
> free(device->label);
> + free(device->zone_info);
> free(device);
> }
>
> diff --git a/kernel-shared/volumes.h b/kernel-shared/volumes.h
> index faaa285dbf11..a64288d566d8 100644
> --- a/kernel-shared/volumes.h
> +++ b/kernel-shared/volumes.h
> @@ -45,6 +45,8 @@ struct btrfs_device {
>
> u64 generation;
>
> + struct btrfs_zoned_device_info *zone_info;
> +
> /* the internal btrfs device id */
> u64 devid;
>
> diff --git a/kernel-shared/zoned.c b/kernel-shared/zoned.c
> new file mode 100644
> index 000000000000..370d93915c6e
> --- /dev/null
> +++ b/kernel-shared/zoned.c
> @@ -0,0 +1,242 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <sys/ioctl.h>
> +#include <linux/fs.h>
> +
> +#include "kernel-lib/list.h"
> +#include "kernel-shared/volumes.h"
> +#include "kernel-shared/zoned.h"
> +#include "common/utils.h"
> +#include "common/device-utils.h"
> +#include "common/messages.h"
> +#include "mkfs/common.h"
> +
> +/* Maximum number of zones to report per ioctl(BLKREPORTZONE)
> call */
> +#define BTRFS_REPORT_NR_ZONES 4096
> +
> +static int btrfs_get_dev_zone_info(struct btrfs_device
> *device);
> +
> +enum btrfs_zoned_model zoned_model(const char *file)
> +{
> + const char *host_aware = "host-aware";
> + const char *host_managed = "host-managed";
> + struct stat st;
> + char model[32];
> + int ret;
> +
> + ret = stat(file, &st);
> + if (ret < 0) {
> + error("zoned: unable to stat %s", file);
> + return -ENOENT;
> + }
> +
> + /* Consider a regular file as non-zoned device */
> + if (!S_ISBLK(st.st_mode))
> + return ZONED_NONE;
> +
> + ret = queue_param(file, "zoned", model, sizeof(model));
> + if (ret <= 0)
> + return ZONED_NONE;
> +
> + if (strncmp(model, host_aware, strlen(host_aware)) == 0)
> + return ZONED_HOST_AWARE;
> + if (strncmp(model, host_managed, strlen(host_managed)) == 0)
> + return ZONED_HOST_MANAGED;
> +
> + return ZONED_NONE;
> +}
> +
> +u64 zone_size(const char *file)
> +{
> + char chunk[32];
> + int ret;
> +
> + ret = queue_param(file, "chunk_sectors", chunk,
> sizeof(chunk));
> + if (ret <= 0)
> + return 0;
> +
> + return strtoull((const char *)chunk, NULL, 10) <<
> SECTOR_SHIFT;
> +}
> +
> +#ifdef BTRFS_ZONED
> +static int report_zones(int fd, const char *file,
> + struct btrfs_zoned_device_info *zinfo)
> +{
> + u64 device_size;
> + u64 zone_bytes = zone_size(file);
> + size_t rep_size;
> + u64 sector = 0;
> + struct blk_zone_report *rep;
> + struct blk_zone *zone;
> + unsigned int i, n = 0;
> + int ret;
> +
> + /*
> + * Zones are guaranteed (by the kernel) to be a power of 2
> number of
> + * sectors. Check this here and make sure that zones are not
> too
> + * small.
> + */
> + if (!zone_bytes || !is_power_of_2(zone_bytes)) {
> + error("zoned: illegal zone size %llu (not a power of 2)",
> + zone_bytes);
> + exit(1);
> + }
> + /*
> + * The zone size must be large enough to hold the initial
> system
> + * block group for mkfs time.
> + */
> + if (zone_bytes < BTRFS_MKFS_SYSTEM_GROUP_SIZE) {
> + error("zoned: illegal zone size %llu (smaller than %d)",
> + zone_bytes, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
> + exit(1);
I see many exit() calls in this patch and other patches.
Any special reasion?
--
Su
> + }
> +
> + /*
> + * No need to use btrfs_device_size() here, since it is
> ensured
> + * that the file is block device.
> + */
> + if (ioctl(fd, BLKGETSIZE64, &device_size) < 0) {
> + error("zoned: ioctl(BLKGETSIZE64) failed on %s (%m)",
> file);
> + exit(1);
> + }
> +
> + /* Allocate the zone information array */
> + zinfo->zone_size = zone_bytes;
> + zinfo->nr_zones = device_size / zone_bytes;
> + if (device_size & (zone_bytes - 1))
> + zinfo->nr_zones++;
> + zinfo->zones = calloc(zinfo->nr_zones, sizeof(struct
> blk_zone));
> + if (!zinfo->zones) {
> + error("zoned: no memory for zone information");
> + exit(1);
> + }
> +
> + /* Allocate a zone report */
> + rep_size = sizeof(struct blk_zone_report) +
> + sizeof(struct blk_zone) * BTRFS_REPORT_NR_ZONES;
> + rep = malloc(rep_size);
> + if (!rep) {
> + error("zoned: no memory for zones report");
> + exit(1);
> + }
> +
> + /* Get zone information */
> + zone = (struct blk_zone *)(rep + 1);
> + while (n < zinfo->nr_zones) {
> + memset(rep, 0, rep_size);
> + rep->sector = sector;
> + rep->nr_zones = BTRFS_REPORT_NR_ZONES;
> +
> + ret = ioctl(fd, BLKREPORTZONE, rep);
> + if (ret != 0) {
> + error("zoned: ioctl BLKREPORTZONE failed (%m)");
> + exit(1);
> + }
> +
> + if (!rep->nr_zones)
> + break;
> +
> + for (i = 0; i < rep->nr_zones; i++) {
> + if (n >= zinfo->nr_zones)
> + break;
> + memcpy(&zinfo->zones[n], &zone[i],
> + sizeof(struct blk_zone));
> + n++;
> + }
> +
> + sector = zone[rep->nr_zones - 1].start +
> + zone[rep->nr_zones - 1].len;
> + }
> +
> + free(rep);
> +
> + return 0;
> +}
> +
> +#endif
> +
> +int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info
> *fs_info)
> +{
> + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
> + struct btrfs_device *device;
> + int ret = 0;
> +
> + /* fs_info->zone_size might not set yet. Use the incomapt flag
> here. */
> + if (!btrfs_fs_incompat(fs_info, ZONED))
> + return 0;
> +
> + list_for_each_entry(device, &fs_devices->devices, dev_list) {
> + /* We can skip reading of zone info for missing devices */
> + if (device->fd == -1)
> + continue;
> +
> + ret = btrfs_get_dev_zone_info(device);
> + if (ret)
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static int btrfs_get_dev_zone_info(struct btrfs_device *device)
> +{
> + struct btrfs_fs_info *fs_info = device->fs_info;
> +
> + /*
> + * Cannot use btrfs_is_zoned here, since fs_info::zone_size
> might not
> + * yet be set.
> + */
> + if (!btrfs_fs_incompat(fs_info, ZONED))
> + return 0;
> +
> + if (device->zone_info)
> + return 0;
> +
> + return btrfs_get_zone_info(device->fd, device->name,
> + &device->zone_info);
> +}
> +
> +int btrfs_get_zone_info(int fd, const char *file,
> + struct btrfs_zoned_device_info **zinfo_ret)
> +{
> +#ifdef BTRFS_ZONED
> + struct btrfs_zoned_device_info *zinfo;
> + int ret;
> +#endif
> + enum btrfs_zoned_model model;
> +
> + *zinfo_ret = NULL;
> +
> + /* Check zone model */
> + model = zoned_model(file);
> + if (model == ZONED_NONE)
> + return 0;
> +
> +#ifdef BTRFS_ZONED
> + zinfo = calloc(1, sizeof(*zinfo));
> + if (!zinfo) {
> + error("zoned: no memory for zone information");
> + exit(1);
> + }
> +
> + zinfo->model = model;
> +
> + /* Get zone information */
> + ret = report_zones(fd, file, zinfo);
> + if (ret != 0) {
> + kfree(zinfo);
> + return ret;
> + }
> + *zinfo_ret = zinfo;
> +#else
> + error("zoned: %s: Unsupported host-%s zoned block device",
> file,
> + model == ZONED_HOST_MANAGED ? "managed" : "aware");
> + if (model == ZONED_HOST_MANAGED)
> + return -EOPNOTSUPP;
> +
> + error("zoned: %s: handling host-aware block device as a
> regular disk",
> + file);
> +#endif
> +
> + return 0;
> +}
> diff --git a/kernel-shared/zoned.h b/kernel-shared/zoned.h
> new file mode 100644
> index 000000000000..461a2d624c67
> --- /dev/null
> +++ b/kernel-shared/zoned.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __BTRFS_ZONED_H__
> +#define __BTRFS_ZONED_H__
> +
> +#include <stdbool.h>
> +#include "kerncompat.h"
> +
> +#ifdef BTRFS_ZONED
> +#include <linux/blkzoned.h>
> +#else
> +struct blk_zone {
> + int dummy;
> +};
> +#endif /* BTRFS_ZONED */
> +
> +/*
> + * Zoned block device models.
> + */
> +enum btrfs_zoned_model {
> + ZONED_NONE = 0,
> + ZONED_HOST_AWARE,
> + ZONED_HOST_MANAGED,
> +};
> +
> +/*
> + * Zone information for a zoned block device.
> + */
> +struct btrfs_zoned_device_info {
> + enum btrfs_zoned_model model;
> + u64 zone_size;
> + u32 nr_zones;
> + struct blk_zone *zones;
> +};
> +
> +enum btrfs_zoned_model zoned_model(const char *file);
> +u64 zone_size(const char *file);
> +int btrfs_get_zone_info(int fd, const char *file,
> + struct btrfs_zoned_device_info **zinfo);
> +int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info
> *fs_info);
> +
> +#endif /* __BTRFS_ZONED_H__ */
next prev parent reply other threads:[~2021-04-26 7:36 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-26 6:27 [PATCH 00/26] btrfs-progs: zoned: zoned block device support Naohiro Aota
2021-04-26 6:27 ` [PATCH 01/26] btrfs-progs: utils: Introduce queue_param helper function Naohiro Aota
2021-04-26 7:26 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 02/26] btrfs-progs: provide fs_info from btrfs_device Naohiro Aota
2021-04-26 7:25 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 03/26] btrfs-progs: build: zoned: Check zoned block device support Naohiro Aota
2021-04-26 6:27 ` [PATCH 04/26] btrfs-progs: zoned: add new ZONED feature flag Naohiro Aota
2021-04-26 7:45 ` Johannes Thumshirn
2021-04-27 15:45 ` David Sterba
2021-04-27 15:46 ` David Sterba
2021-04-28 0:07 ` Naohiro Aota
2021-04-26 6:27 ` [PATCH 05/26] btrfs-progs: zoned: get zone information of zoned block devices Naohiro Aota
2021-04-26 7:32 ` Su Yue [this message]
2021-04-27 16:45 ` David Sterba
2021-04-28 0:09 ` Naohiro Aota
2021-04-26 6:27 ` [PATCH 06/26] btrfs-progs: zoned: check and enable ZONED mode Naohiro Aota
2021-04-26 7:48 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 07/26] btrfs-progs: zoned: introduce max_zone_append_size Naohiro Aota
2021-04-26 7:51 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 08/26] btrfs-progs: zoned: disallow mixed-bg in ZONED mode Naohiro Aota
2021-04-26 7:56 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 09/26] btrfs-progs: zoned: allow zoned filesystems on non-zoned block devices Naohiro Aota
2021-04-26 13:43 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 10/26] btrfs-progs: zoned: implement log-structured superblock for ZONED mode Naohiro Aota
2021-04-26 16:04 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 11/26] btrfs-progs: zoned: implement zoned chunk allocator Naohiro Aota
2021-04-27 17:19 ` David Sterba
2021-04-27 19:58 ` Johannes Thumshirn
2021-04-26 6:27 ` [PATCH 12/26] btrfs-progs: zoned: load zone's allocation offset Naohiro Aota
2021-04-26 6:27 ` [PATCH 13/26] btrfs-progs: zoned: implement sequential extent allocation Naohiro Aota
2021-04-26 6:27 ` [PATCH 14/26] btrfs-progs: zoned: calculate allocation offset for conventional zones Naohiro Aota
2021-04-26 6:27 ` [PATCH 15/26] btrfs-progs: zoned: redirty clean extent buffers in zoned btrfs Naohiro Aota
2021-04-26 6:27 ` [PATCH 16/26] btrfs-progs: zoned: reset zone of freed block group Naohiro Aota
2021-04-26 6:27 ` [PATCH 17/26] btrfs-progs: zoned: support resetting zoned device Naohiro Aota
2021-04-26 6:27 ` [PATCH 18/26] btrfs-progs: zoned: support zero out on zoned block device Naohiro Aota
2021-04-26 6:27 ` [PATCH 19/26] btrfs-progs: zoned: support wiping SB on sequential write zone Naohiro Aota
2021-04-26 6:27 ` [PATCH 20/26] btrfs-progs: mkfs: zoned: detect and enable zoned feature flag Naohiro Aota
2021-04-26 6:27 ` [PATCH 21/26] btrfs-progs: mkfs: zoned: check incompatible features with zoned btrfs Naohiro Aota
2021-04-26 6:27 ` [PATCH 22/26] btrfs-progs: mkfs: zoned: tweak initial system block group placement Naohiro Aota
2021-04-26 6:27 ` [PATCH 23/26] btrfs-progs: mkfs: zoned: use sbwrite to update superblock Naohiro Aota
2021-04-26 6:27 ` [PATCH 24/26] btrfs-progs: zoned: wipe temporary superblocks in superblock log zone Naohiro Aota
2021-04-26 6:27 ` [PATCH 25/26] btrfs-progs: zoned: device-add: support ZONED device Naohiro Aota
2021-04-26 6:27 ` [PATCH 26/26] btrfs-progs: zoned: introduce zoned support for device replace Naohiro Aota
2021-04-29 15:53 ` [PATCH 00/26] btrfs-progs: zoned: zoned block device support David Sterba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bla1pkg4.fsf@damenly.su \
--to=l@damenly.su \
--cc=dsterba@suse.com \
--cc=josef@toxicpanda.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=naohiro.aota@wdc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox