From fecf7be637d6549133d88b58fb91cb95377fb5bb Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Mon, 2 Jan 2023 01:50:02 +0000 Subject: [PATCH] Add two tools: mkdoubledirs and gensamehash mkdoubledirs creates pairs of directories a/a, b/b, c/c etc. This is to test file lookup code: there must be a directory named blah only if the current directory is named blah too. gensamehash generates file names with the same XFS hash to test the code that resolves collisions. In principle, can be updated for other hashes: ext*, exfat, etc. --- .gitignore | 10 ++-- img/makefile | 75 ++++++++++++++++++++++++++- tools/gensamehash.c | 117 +++++++++++++++++++++++++++++++++++++++++++ tools/makefile | 12 ++++- tools/mkdoubledirs.c | 58 +++++++++++++++++++++ 5 files changed, 264 insertions(+), 8 deletions(-) create mode 100644 tools/gensamehash.c create mode 100644 tools/mkdoubledirs.c diff --git a/.gitignore b/.gitignore index 501d65e..7f12de8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,10 +8,12 @@ umka_fuse umka_os umka_ping umka_gen_devices_dat -mkdirrange -mkfilepattern -lfbviewx -randdir +tools/mkdirrange +tools/mkdoubledirs +tools/gensamehash +tools/mkfilepattern +tools/lfbviewx +tools/randdir *.img *.img.xz *.img.gz diff --git a/img/makefile b/img/makefile index 25bdc25..7d8371a 100644 --- a/img/makefile +++ b/img/makefile @@ -1,5 +1,6 @@ RANDDIR=../tools/randdir MKDIRRANGE=../tools/mkdirrange +MKDOUBLEDIRS=../tools/mkdoubledirs MKFILEPATTERN=../tools/mkfilepattern DIRTOTEST=python3 ../tools/dirtotest.py MOUNT_OPT=-t xfs @@ -15,7 +16,7 @@ s4k: xfs_v4_ftype0_s4k_b4k_n8k.img unicode: xfs_v4_unicode.img -v5: xfs_v5_ftype1_s05k_b2k_n8k.img xfs_v5_files_s05k_b4k_n8k.img xfs_bigtime.img xfs_nrext64.img +v5: xfs_v5_ftype1_s05k_b2k_n8k.img xfs_v5_files_s05k_b4k_n8k.img xfs_bigtime.img xfs_nrext64.img xfs_lookup_v5.img xfs_lookup_v4.img coverage: jfs.img xfs_borg_bit.img xfs_short_dir_i8.img @@ -37,6 +38,76 @@ jfs.img: parted --script $@ mktable gpt parted --script --align optimal $@ mkpart primary 1MiB 100% +xfs_lookup_v4.img: + fallocate -l 10GiB $@ + mkfs.xfs -m crc=0 $@ + sudo mount $(MOUNT_OPT) $@ $(TEMP_DIR) + sudo chown $$USER $(TEMP_DIR) -R +# + mkdir $(TEMP_DIR)/dir_sf + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_sf d 5 +# + mkdir $(TEMP_DIR)/dir_block + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_block d 50 +# + mkdir $(TEMP_DIR)/dir_leaf + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_leaf d 500 +# + mkdir $(TEMP_DIR)/dir_node + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_node d 2000 +# + mkdir $(TEMP_DIR)/dir_btree_l1a + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l1a d 5000 +# + mkdir $(TEMP_DIR)/dir_btree_l1b + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l1b d 50000 +# + mkdir $(TEMP_DIR)/dir_btree_l1c + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l1c d 500000 +# + mkdir $(TEMP_DIR)/dir_btree_l2 + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l2 d 2000000 +# + sudo umount $(TEMP_DIR) + fallocate -i -o 0 -l 1MiB $@ + parted --script --align optimal $@ mktable msdos + parted --script --align optimal $@ mkpart primary xfs 1MiB 100% + +xfs_lookup_v5.img: + fallocate -l 10GiB $@ + mkfs.xfs -m crc=1 $@ + sudo mount $(MOUNT_OPT) $@ $(TEMP_DIR) + sudo chown $$USER $(TEMP_DIR) -R +# + mkdir $(TEMP_DIR)/dir_sf + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_sf d 5 +# + mkdir $(TEMP_DIR)/dir_block + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_block d 50 +# + mkdir $(TEMP_DIR)/dir_leaf + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_leaf d 500 +# + mkdir $(TEMP_DIR)/dir_node + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_node d 2000 +# + mkdir $(TEMP_DIR)/dir_btree_l1a + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l1a d 5000 +# + mkdir $(TEMP_DIR)/dir_btree_l1b + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l1b d 50000 +# + mkdir $(TEMP_DIR)/dir_btree_l1c + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l1c d 500000 +# + mkdir $(TEMP_DIR)/dir_btree_l2 + $(MKDOUBLEDIRS) $(TEMP_DIR)/dir_btree_l2 d 2000000 +# + sudo umount $(TEMP_DIR) + fallocate -i -o 0 -l 1MiB $@ + parted --script --align optimal $@ mktable msdos + parted --script --align optimal $@ mkpart primary xfs 1MiB 100% + xfs_nrext64.img: fallocate -l 3000MiB $@ mkfs.xfs -i nrext64=1 $@ @@ -118,7 +189,7 @@ xfs_short_dir_i8.img: # sudo umount $(TEMP_DIR) fallocate -i -o 0 -l 1MiB $@ - parted --script $@ mktable gpt + parted --script $@ mktable gpt # FIXME: all msdos parted --script --align optimal $@ mkpart primary 1MiB 100% xfs_v4_ftype0_s05k_b2k_n8k.img: diff --git a/tools/gensamehash.c b/tools/gensamehash.c new file mode 100644 index 0000000..1fb8220 --- /dev/null +++ b/tools/gensamehash.c @@ -0,0 +1,117 @@ +/* + SPDX-License-Identifier: GPL-2.0-or-later + + UMKa - User-Mode KolibriOS developer tools + gensamehash - make directories with same names inside: dirname/dirname, + useful for search testing + + Copyright (C) 2022 Ivan Baravy +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_LEN 18 +#define rol32(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) + +// the hash function has been taken from XFS docs with minor edits +uint32_t xfs_da_hashname(const char *name, int namelen) { + uint32_t hash; + + /* + * Do four characters at a time as long as we can. + */ + for (hash = 0; namelen >= 4; namelen -= 4, name += 4) { + hash = (name[0] << 21) ^ (name[1] << 14) ^ (name[2] << 7) ^ + (name[3] << 0) ^ rol32(hash, 7 * 4); + } + /* + * Now do the rest of the characters. + */ + switch (namelen) { + case 3: + return (name[0] << 14) ^ (name[1] << 7) ^ (name[2] << 0) ^ + rol32(hash, 7 * 3); + case 2: + return (name[0] << 7) ^ (name[1] << 0) ^ rol32(hash, 7 * 2); + case 1: + return (name[0] << 0) ^ rol32(hash, 7 * 1); + default: /* case 0: */ + return hash; + } +} + +char name[256]; +char hash_filename[256]; + +void increment(char *num) { + for (char *d = num + NUM_LEN; d > num; d--) { + if (*d < '9') { + d[0]++; + break; + } else { + *d = '0'; + } + } +} + +void int_handler(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)info; + (void)context; + fprintf(stderr, "# cur name is %s\n", name); +} + +int main(int argc, char *argv[]) +{ + uint32_t hash; + int hash_cnt = 0; + uint64_t start_num; + if (argc != 4) { + fprintf(stderr, "gensamehash \n"); + exit(1); + } + + hash = strtoul(argv[1], NULL, 16); + sscanf(argv[2], "%i", &hash_cnt); + sscanf(argv[3], "%" SCNu64, &start_num); + + fprintf(stderr, "pid: %u\n", getpid()); + sprintf(hash_filename, "hash_0x%8.8" PRIx32 ".%u", hash, getpid()); + + sprintf(name, "d%18.18" PRIu64, start_num); + + struct sigaction sa; + sa.sa_sigaction = int_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + if (sigaction(SIGUSR1, &sa, NULL) == -1) { + fprintf(stderr, "Can't install SIGUSR1 handler!\n"); + exit(1); + } + + while (true) { + uint32_t h = xfs_da_hashname(name, NUM_LEN+1); + if (h == hash) { + FILE *f = fopen(hash_filename, "a+"); + fprintf(f, "%7.7i %s\n", hash_cnt, name); + fclose(f); + hash_cnt++; + } +// fprintf(stderr, "# hash of %s is 0x%8.8x\n", name, h); + increment(name); + } + + return 0; +} diff --git a/tools/makefile b/tools/makefile index 3ad32ab..d2f311f 100644 --- a/tools/makefile +++ b/tools/makefile @@ -7,7 +7,14 @@ CFLAGS=$(WARNINGS) $(NOWARNINGS) -std=c11 -O2 \ -DNDEBUG -D_POSIX_C_SOURCE=200809L -fno-pie LDFLAGS=-no-pie -all: mkdirrange mkfilepattern lfbviewx randdir covpreproc +all: mkdirrange mkfilepattern lfbviewx randdir covpreproc mkdoubledirs \ + gensamehash + +gensamehash: gensamehash.c + $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ + +mkdoubledirs: mkdoubledirs.c + $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ mkdirrange: mkdirrange.c $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ @@ -27,4 +34,5 @@ covpreproc: covpreproc.c .PHONY: all clean clean: - rm -f *.o mkdirrange mkfilepattern lfbviewx randdir covpreproc + rm -f *.o mkdirrange mkfilepattern lfbviewx randdir covpreproc \ + mkdoubledirs gensamehash diff --git a/tools/mkdoubledirs.c b/tools/mkdoubledirs.c new file mode 100644 index 0000000..03bf78f --- /dev/null +++ b/tools/mkdoubledirs.c @@ -0,0 +1,58 @@ +/* + SPDX-License-Identifier: GPL-2.0-or-later + + UMKa - User-Mode KolibriOS developer tools + mkdoubledirs - make directories with same names inside: dirname/dirname, + useful for search testing + + Copyright (C) 2022 Ivan Baravy +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + const char *prefix; + const char *path; + unsigned count; + if (argc != 4) { + fprintf(stderr, "mkdoubledirs \n"); + exit(1); + } + path = argv[1]; + prefix = argv[2]; + sscanf(argv[3], "%u", &count); + + if (chdir(path)) { + fprintf(stderr, "Can't change dir to %s: %s\n", path, strerror(errno)); + exit(1); + } + char dirname[256]; + + for(unsigned cur = 0; cur < count; cur++) { + sprintf(dirname, "%s%10.10u", prefix, cur); + if(mkdirat(AT_FDCWD, dirname, 0755)) { + fprintf(stderr, "Can't mkdir %s: %s\n", dirname, strerror(errno)); + exit(1); + } + int dirfd = open(dirname, O_DIRECTORY); + if (dirfd == -1) { + fprintf(stderr, "Can't open %s: %s\n", dirname, strerror(errno)); + exit(1); + } + if(mkdirat(dirfd, dirname, 0755)) { + fprintf(stderr, "Can't mkdir %s: %s\n", dirname, strerror(errno)); + exit(1); + } + close(dirfd); + } + + return 0; +}