Skip to content

Commit 864a9a1

Browse files
committed
Use hash func to boost file creation and lookup
Introduce a hash-based mechanism to speed up file creation and lookup operations. The hash function enables faster access to extent and logical block extent index, improving overall filesystem performance. hash_code = file_hash(file_name); extent index = hash_code / SIMPLEFS_MAX_BLOCKS_PER_EXTENT block index = hash_code % SIMPLEFS_MAX_BLOCKS_PER_EXTENT; Use perf to measure: 1. File Creation (random) Legacy: 259.842753513 seconds time elapsed 23.000247000 seconds user 150.380145000 seconds sys fnv1a: 172.464862354 seconds time elapsed 16.456851000 seconds user 117.377930000 seconds sys full_name_hash: 222.274028604 seconds time elapsed 20.794966000 seconds user 151.941876000 seconds sys hash64: 210.738022828 seconds time elapsed 20.578577000 seconds user 138.393533000 seconds sys 2. File Listing (random) Legacy: min time: 0.00171 s max time: 0.03799 s avg time: 0.00423332 s tot time: 129.539510 s fnv1a: min time: 0.00163 s max time: 0.07574 s avg time: 0.00247343 s tot time: 75.686920 s full_name_hash: min time: 0.00171 s max time: 0.03588 s avg time: 0.00305601 s tot time: 93.514040 s hash64: min time: 0.00167 s max time: 0.07705 s avg time: 0.00261552 s tot time: 80.034760 s 3. files Removal (Random) Legacy : 106.921706288 seconds time elapsed 16.987883000 seconds user 91.268661000 seconds sys fnv1a: 94.012202913 seconds time elapsed 20.617263000 seconds user 73.219170000 seconds sys full_name_hash: 86.132655220 seconds time elapsed 19.180209000 seconds user 68.476075000 seconds sys hash64: 85.684199320 seconds time elapsed 16.643633000 seconds user 70.499664000 seconds sys
1 parent d1cf3ba commit 864a9a1

File tree

5 files changed

+340
-184
lines changed

5 files changed

+340
-184
lines changed

Makefile

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
obj-m += simplefs.o
2-
simplefs-objs := fs.o super.o inode.o file.o dir.o extent.o symlink.o
2+
simplefs-objs := fs.o super.o inode.o file.o dir.o extent.o symlink.o hash.o
33
KDIR ?= /lib/modules/$(shell uname -r)/build
44

5+
CONFIG := .config
6+
CONFIG_H := config.h
7+
58
MKFS = mkfs.simplefs
9+
MENUCONFIG := kconfig-mconf
610

7-
all: $(MKFS)
11+
all: $(MKFS) $(CONFIG_H)
812
make -C $(KDIR) M=$(PWD) modules
913

1014
IMAGE ?= test.img
@@ -22,6 +26,30 @@ $(IMAGE): $(MKFS)
2226
dd if=/dev/zero of=${IMAGE} bs=1M count=${IMAGESIZE}
2327
./$< $(IMAGE)
2428

29+
$(CONFIG_H): $(CONFIG)
30+
@echo "/*" > $(CONFIG_H)
31+
@echo " * Automatically generated file; DO NOT EDIT." >> $(CONFIG_H)
32+
@echo " * Configuration" >> $(CONFIG_H)
33+
@echo " */" >> $(CONFIG_H)
34+
@echo "" >> $(CONFIG_H)
35+
@sed \
36+
-e '/^$$/d' \
37+
-e '/^[[:space:]]*# *$$/d' \
38+
-e '/^[[:space:]]*# Automatically/d' \
39+
-e '/^[[:space:]]*# Configuration/d' \
40+
-e '/^[[:space:]]*# \(CONFIG_[A-Z0-9_]*\) is not set/ s//#undef \1/' \
41+
-e '/^[[:space:]]*CONFIG_[A-Z0-9_]*=y/ s/^[[:space:]]*\(CONFIG_[A-Z0-9_]*\)=y/#define \1 1/' \
42+
-e '/^[[:space:]]*CONFIG_[A-Z0-9_]*=[0-9]\+/ s/^[[:space:]]*\(CONFIG_[A-Z0-9_]*\)=\([0-9]*\)/#define \1 \2/' \
43+
-e '/^[[:space:]]*# / s/^[[:space:]]*# \(.*\)/\/\* \1 \*\//' \
44+
$(CONFIG) >> $(CONFIG_H)
45+
46+
menuconfig:
47+
$(MENUCONFIG) Kconfig
48+
49+
.config:
50+
@echo "Creating default .config"
51+
@echo "CONFIG_SIMPLEFS_HASH_FNV1A=y" > .config
52+
2553
journal: $(JOURNAL)
2654

2755
$(JOURNAL):
@@ -34,6 +62,9 @@ check: all
3462
clean:
3563
make -C $(KDIR) M=$(PWD) clean
3664
rm -f *~ $(PWD)/*.ur-safe
37-
rm -f $(MKFS) $(IMAGE) $(JOURNAL)
65+
rm -f $(MKFS) $(IMAGE) $(JOURNAL) config.h
66+
67+
distclean: clean
68+
rm -f $(CONFIG)
3869

39-
.PHONY: all clean journal
70+
.PHONY: all clean journal menuconfig distclean

dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static int simplefs_iterate(struct file *dir, struct dir_context *ctx)
8181
continue;
8282
}
8383

84-
for (fi = 0; fi < SIMPLEFS_FILES_PER_BLOCK;) {
84+
for (fi = 0; fi < SIMPLEFS_FILES_PER_BLOCK && dblock->nr_files;) {
8585
if (dblock->files[fi].inode != 0) {
8686
if (offset) {
8787
offset--;

hash.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <linux/crc32.h>
2+
#include <linux/hash.h>
3+
#include <linux/stringhash.h>
4+
#include <linux/types.h>
5+
#include "config.h"
6+
#include "simplefs.h"
7+
8+
9+
#if defined(CONFIG_SIMPLEFS_HASH_HASH64)
10+
static uint64_t _hash64(const char *name, size_t len)
11+
{
12+
uint32_t val = crc32(0, name, len);
13+
return hash_64(
14+
val, ilog2(SIMPLEFS_MAX_EXTENTS * SIMPLEFS_MAX_BLOCKS_PER_EXTENT));
15+
}
16+
#elif defined(CONFIG_SIMPLEFS_HASH_FNV1A)
17+
static uint64_t _fnv1a_64(const char *str)
18+
{
19+
uint64_t h = 0xcbf29ce484222325ULL;
20+
while (*str) {
21+
h ^= (unsigned char) (*str++);
22+
h *= 0x100000001b3ULL;
23+
}
24+
return h;
25+
}
26+
#endif
27+
28+
uint32_t simplefs_hash(struct dentry *dentry)
29+
{
30+
#if defined(CONFIG_SIMPLEFS_HASH_HASH64)
31+
return _hash64(dentry->d_name.name, strlen(dentry->d_name.name));
32+
#elif defined(CONFIG_SIMPLEFS_HASH_FNV1A)
33+
return _fnv1a_64(dentry->d_name.name);
34+
#elif defined(CONFIG_SIMPLEFS_HASH_FULLNAME)
35+
return full_name_hash(dentry, dentry->d_name.name,
36+
strlen(dentry->d_name.name));
37+
#else
38+
#error "No hash method selected!"
39+
#endif
40+
}

0 commit comments

Comments
 (0)