From 1cdcf41ac72607ac72cefbb754aca7287e20b377 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 27 Sep 2021 14:35:16 -0700 Subject: [PATCH] Move more block read/write functions to util We're adding another command that does block IO so move some block reading and writing functions out of mkfs. We also grow a few function variants and call the write_sync variant from mkfs instead of having it manually sync. Signed-off-by: Zach Brown --- utils/src/mkfs.c | 50 +++--------------------- utils/src/util.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ utils/src/util.h | 8 ++++ 3 files changed, 112 insertions(+), 44 deletions(-) diff --git a/utils/src/mkfs.c b/utils/src/mkfs.c index 6d2213e6..69999c16 100644 --- a/utils/src/mkfs.c +++ b/utils/src/mkfs.c @@ -32,30 +32,6 @@ #include "leaf_item_hash.h" #include "blkid.h" -/* - * Update the block header fields and write out the block. - */ -static int write_block(int fd, u32 magic, __le64 fsid, u64 seq, u64 blkno, - int shift, struct scoutfs_block_header *hdr) -{ - size_t size = 1ULL << shift; - ssize_t ret; - - hdr->magic = cpu_to_le32(magic); - hdr->fsid = fsid; - hdr->blkno = cpu_to_le64(blkno); - hdr->seq = cpu_to_le64(seq); - hdr->crc = cpu_to_le32(crc_block(hdr, size)); - - ret = pwrite(fd, hdr, size, blkno << shift); - if (ret != size) { - fprintf(stderr, "write to blkno %llu returned %zd: %s (%d)\n", - blkno, ret, strerror(errno), errno); - return -errno; - } - - return 0; -} /* * Return the order of the length of a free extent, which we define as @@ -356,33 +332,19 @@ static int do_mkfs(struct mkfs_args *args) } /* write the super block to data dev and meta dev*/ - ret = write_block(data_fd, SCOUTFS_BLOCK_MAGIC_SUPER, fsid, 1, - SCOUTFS_SUPER_BLKNO, SCOUTFS_BLOCK_SM_SHIFT, - &super->hdr); + ret = write_block_sync(data_fd, SCOUTFS_BLOCK_MAGIC_SUPER, fsid, 1, + SCOUTFS_SUPER_BLKNO, SCOUTFS_BLOCK_SM_SHIFT, + &super->hdr); if (ret) goto out; - if (fsync(data_fd)) { - ret = -errno; - fprintf(stderr, "failed to fsync '%s': %s (%d)\n", - args->data_device, strerror(errno), errno); - goto out; - } - super->flags |= cpu_to_le64(SCOUTFS_FLAG_IS_META_BDEV); - ret = write_block(meta_fd, SCOUTFS_BLOCK_MAGIC_SUPER, fsid, - 1, SCOUTFS_SUPER_BLKNO, SCOUTFS_BLOCK_SM_SHIFT, - &super->hdr); + ret = write_block_sync(meta_fd, SCOUTFS_BLOCK_MAGIC_SUPER, fsid, + 1, SCOUTFS_SUPER_BLKNO, SCOUTFS_BLOCK_SM_SHIFT, + &super->hdr); if (ret) goto out; - if (fsync(meta_fd)) { - ret = -errno; - fprintf(stderr, "failed to fsync '%s': %s (%d)\n", - args->meta_device, strerror(errno), errno); - goto out; - } - uuid_unparse(super->uuid, uuid_str); printf("Created scoutfs filesystem:\n" diff --git a/utils/src/util.c b/utils/src/util.c index 9c3aa6ef..53a45ed2 100644 --- a/utils/src/util.c +++ b/utils/src/util.c @@ -10,6 +10,8 @@ #include #include "util.h" +#include "format.h" +#include "crc.h" #define ENV_PATH "SCOUTFS_MOUNT_PATH" @@ -98,3 +100,99 @@ int read_block(int fd, u64 blkno, int shift, void **ret_val) return 0; } } + +int read_block_crc(int fd, u64 blkno, int shift, void **ret_val) +{ + struct scoutfs_block_header *hdr; + size_t size = 1ULL << shift; + int ret; + u32 crc; + + ret = read_block(fd, blkno, shift, ret_val); + if (ret == 0) { + hdr = *ret_val; + crc = crc_block(hdr, size); + if (crc != le32_to_cpu(hdr->crc)) { + fprintf(stderr, "crc of read blkno %llu failed, stored %08x != calculated %08x\n", + blkno, le32_to_cpu(hdr->crc), crc); + free(*ret_val); + *ret_val = NULL; + ret = -EIO; + } + } + + return ret; +} + +int read_block_verify(int fd, u32 magic, u64 fsid, u64 blkno, int shift, void **ret_val) +{ + struct scoutfs_block_header *hdr = NULL; + int ret; + + ret = read_block_crc(fd, blkno, shift, ret_val); + if (ret == 0) { + hdr = *ret_val; + ret = -EIO; + if (le32_to_cpu(hdr->magic) != magic) + fprintf(stderr, "read blkno %llu has bad magic %08x != expected %08x\n", + blkno, le32_to_cpu(hdr->magic), magic); + else if (fsid != 0 && le32_to_cpu(hdr->fsid) != fsid) + fprintf(stderr, "read blkno %llu has bad fsid %016llx != expected %016llx\n", + blkno, le64_to_cpu(hdr->fsid), fsid); + else if (le32_to_cpu(hdr->blkno) != blkno) + fprintf(stderr, "read blkno %llu has bad blkno %llu != expected %llu\n", + blkno, le64_to_cpu(hdr->blkno), blkno); + else + ret = 0; + + if (ret < 0) { + free(*ret_val); + *ret_val = NULL; + } + } + + + return ret; +} + +/* + * Update the block header fields and write out the block. + */ +int write_block(int fd, u32 magic, __le64 fsid, u64 seq, u64 blkno, + int shift, struct scoutfs_block_header *hdr) +{ + size_t size = 1ULL << shift; + ssize_t ret; + + hdr->magic = cpu_to_le32(magic); + hdr->fsid = fsid; + hdr->blkno = cpu_to_le64(blkno); + hdr->seq = cpu_to_le64(seq); + hdr->crc = cpu_to_le32(crc_block(hdr, size)); + + ret = pwrite(fd, hdr, size, blkno << shift); + if (ret != size) { + fprintf(stderr, "write to blkno %llu returned %zd: %s (%d)\n", + blkno, ret, strerror(errno), errno); + return -errno; + } + + return 0; +} + +int write_block_sync(int fd, u32 magic, __le64 fsid, u64 seq, u64 blkno, + int shift, struct scoutfs_block_header *hdr) +{ + int ret = write_block(fd, magic, fsid, seq, blkno, shift, hdr); + if (ret != 0) + return ret; + + if (fsync(fd)) { + ret = -errno; + fprintf(stderr, "fsync after write to blkno %llu failed: %s (%d)\n", + blkno, strerror(errno), errno); + return ret; + } + + return 0; +} diff --git a/utils/src/util.h b/utils/src/util.h index b504a5c0..3b05e1f1 100644 --- a/utils/src/util.h +++ b/utils/src/util.h @@ -113,6 +113,14 @@ static inline int memcmp_lens(const void *a, int a_len, int get_path(char *path, int flags); int read_block(int fd, u64 blkno, int shift, void **ret_val); +int read_block_crc(int fd, u64 blkno, int shift, void **ret_val); +int read_block_verify(int fd, u32 magic, u64 fsid, u64 blkno, int shift, void **ret_val); + +struct scoutfs_block_header; +int write_block(int fd, u32 magic, __le64 fsid, u64 seq, u64 blkno, + int shift, struct scoutfs_block_header *hdr); +int write_block_sync(int fd, u32 magic, __le64 fsid, u64 seq, u64 blkno, + int shift, struct scoutfs_block_header *hdr); #define __stringify_1(x) #x #define __stringify(x) __stringify_1(x)