Daniel, It missed to add doc entry, just found the issue.
Thanks, On 6/17/25 22:04, Daniel Lee wrote: > A new command 'test_create_perf', has been introduced to measure > the performance of creating and deleting many files. > > Signed-off-by: Daniel Lee <chul...@google.com> > --- > v3: make sync optional for deletion phase > v2: Rename command and make fsync optional > --- > tools/f2fs_io/f2fs_io.c | 146 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 146 insertions(+) > > diff --git a/tools/f2fs_io/f2fs_io.c b/tools/f2fs_io/f2fs_io.c > index 6531b55..f6649f1 100644 > --- a/tools/f2fs_io/f2fs_io.c > +++ b/tools/f2fs_io/f2fs_io.c > @@ -2092,6 +2092,151 @@ static void do_ftruncate(int argc, char **argv, const > struct cmd_desc *cmd) > exit(0); > } > > +#define test_create_perf_desc "measure file creation speed" > +#define test_create_perf_help > \ > +"f2fs_io test_create_perf [-s] [-S] <dir> <num_files> <size_kb>\n\n" \ > +"Measures file creation and deletion performance.\n" \ > +" <dir> The target directory where files will be created.\n" > \ > +" <num_files> The total number of files to create and delete.\n" \ > +" <size_kb> The size of each file in kb.\n" \ > +" [-s] Call fsync() after each file creation.\n" \ > +" [-S] Call sync() after deleting all files.\n" > + > +static void do_test_create_perf(int argc, char **argv, const struct cmd_desc > *cmd) > +{ > + bool do_fsync = false, do_sync = false; > + int opt; > + char *dir; > + int num_files; > + int size_kb; > + char *write_buffer = NULL; > + > + while ((opt = getopt(argc, argv, "sS")) != -1) { > + switch (opt) { > + case 's': > + do_fsync = true; > + break; > + case 'S': > + do_sync = true; > + break; > + default: > + fputs(cmd->cmd_help, stderr); > + exit(1); > + } > + } > + > + argc -= optind; > + argv += optind; > + > + if (argc != 3) { > + fputs("Excess arguments\n\n", stderr); > + fputs(cmd->cmd_help, stderr); > + exit(1); > + } > + > + dir = argv[0]; > + num_files = atoi(argv[1]); > + size_kb = atoi(argv[2]); > + > + if (num_files <= 0) { > + fprintf(stderr, "Error: Number of files must be positive.\n"); > + exit(1); > + } > + > + if (size_kb > 0) { > + write_buffer = malloc(size_kb * 1024); > + if (!write_buffer) { > + perror("Failed to allocate write buffer"); > + exit(1); > + } > + memset(write_buffer, 'a', size_kb * 1024); > + } > + > + // Creation Phase > + printf("Starting test: Creating %d files of %dKB each in %s (fsync: > %s)\n", > + num_files, size_kb, dir, > + do_fsync ? "Enabled" : "Disabled"); > + > + struct timespec create_start, create_end; > + > + clock_gettime(CLOCK_MONOTONIC, &create_start); > + > + for (int i = 0; i < num_files; i++) { > + char path[1024]; > + > + snprintf(path, sizeof(path), "%s/test_file_%d", dir, i); > + > + int fd = open(path, O_WRONLY | O_CREAT, 0644); > + > + if (fd < 0) { > + perror("Error opening file"); > + continue; > + } > + if (size_kb > 0) { > + if (write(fd, write_buffer, size_kb * 1024) < 0) > + perror("Error writing to file"); > + } > + > + if (do_fsync) > + fsync(fd); > + > + close(fd); > + } > + > + clock_gettime(CLOCK_MONOTONIC, &create_end); > + > + > + // Deletion Phase > + printf("Deleting %d created files (sync: %s)\n", num_files, > + do_sync ? "Enabled" : "Disabled"); > + > + struct timespec del_start, del_end; > + > + clock_gettime(CLOCK_MONOTONIC, &del_start); > + > + for (int i = 0; i < num_files; i++) { > + char path[1024]; > + > + snprintf(path, sizeof(path), "%s/test_file_%d", dir, i); > + if (unlink(path) != 0) > + perror("Error unlinking file"); > + } > + > + if (do_sync) > + sync(); > + > + clock_gettime(CLOCK_MONOTONIC, &del_end); > + > + long create_seconds = create_end.tv_sec - create_start.tv_sec; > + long create_ns = create_end.tv_nsec - create_start.tv_nsec; > + double create_time_s = (double)create_seconds + (double)create_ns / > 1000000000.0; > + double create_throughput = (create_time_s > 0) ? (num_files / > create_time_s) : 0; > + > + long del_seconds = del_end.tv_sec - del_start.tv_sec; > + long del_ns = del_end.tv_nsec - del_start.tv_nsec; > + double del_time_s = (double)del_seconds + (double)del_ns / 1000000000.0; > + double del_throughput = (del_time_s > 0) ? (num_files / del_time_s) : 0; > + > + > printf("Operation,total_files,file_size_kb,total_time_s,throughput_files_per_sec\n"); > + > + printf("CREATE,%d,%d,%.4f,%.2f\n", > + num_files, > + size_kb, > + create_time_s, > + create_throughput); > + > + printf("DELETE,%d,%d,%.4f,%.2f\n", > + num_files, > + size_kb, > + del_time_s, > + del_throughput); > + > + if (write_buffer) > + free(write_buffer); > + > + exit(0); > +} > + > #define CMD_HIDDEN 0x0001 > #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 } > #define _CMD(name) { #name, do_##name, NULL, NULL, CMD_HIDDEN } > @@ -2140,6 +2285,7 @@ const struct cmd_desc cmd_list[] = { > CMD(get_advise), > CMD(ioprio), > CMD(ftruncate), > + CMD(test_create_perf), > { NULL, NULL, NULL, NULL, 0 } > }; > _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel