1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020 IBM.
6 * simple mmap write multithreaded test for testing enospc
19 #define pr_debug(fmt, ...) do { \
21 printf (fmt, ##__VA_ARGS__); \
29 static float file_ratio[2] = {0.5, 0.5};
30 static unsigned long fsize = 0;
31 static char *base_dir = ".";
32 static char *ratio = "1";
34 static bool use_fallocate = false;
35 static bool verbose = false;
37 pthread_barrier_t bar;
39 void handle_sigbus(int sig)
41 pr_debug("Enospc test failed with SIGBUS\n");
45 void enospc_test(int id)
49 char fpath[255] = {0};
51 unsigned long size = 0;
54 * Comma separated values against -r option indicates that the file
55 * should be divided into two small files.
56 * The file_ratio specifies the proportion in which the file sizes must
59 * Half of the files will be divided into size of the first ratio and the
60 * rest of the following ratio
64 size = fsize * file_ratio[0];
66 size = fsize * file_ratio[1];
68 pthread_barrier_wait(&bar);
70 sprintf(fpath, "%s/mmap-file-%d", base_dir, id);
71 pr_debug("Test write phase starting file %s fsize %lu, id %d\n", fpath, size, id);
73 signal(SIGBUS, handle_sigbus);
75 fd = open(fpath, O_RDWR | O_CREAT, 0644);
77 pr_debug("Open failed\n");
82 assert(fallocate(fd, 0, 0, size) == 0);
84 assert(ftruncate(fd, size) == 0);
86 addr = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
87 assert(addr != MAP_FAILED);
89 for (i = 0; i < size; i++) {
93 assert(munmap(addr, size) != -1);
95 pr_debug("Test write phase completed...file %s, fsize %lu, id %d\n", fpath, size, id);
98 void *spawn_test_thread(void *arg)
100 struct thread_s *thread_info = (struct thread_s *)arg;
102 enospc_test(thread_info->id);
106 void _run_test(int threads)
109 pthread_t tid[threads];
111 pthread_barrier_init(&bar, NULL, threads+1);
112 for (i = 0; i < threads; i++) {
113 struct thread_s *thread_info = (struct thread_s *) malloc(sizeof(struct thread_s));
115 assert(pthread_create(&tid[i], NULL, spawn_test_thread, thread_info) == 0);
118 pthread_barrier_wait(&bar);
120 for (i = 0; i < threads; i++) {
121 assert(pthread_join(tid[i], NULL) == 0);
124 pthread_barrier_destroy(&bar);
128 static void usage(void)
130 printf("\nUsage: t_enospc [options]\n\n"
132 " -s size file size\n"
133 " -p path set base path\n"
134 " -f fallocate use fallocate instead of ftruncate\n"
135 " -v verbose print debug information\n"
136 " -r ratio ratio of file sizes, ',' separated values (def: 0.5,0.5)\n");
139 int main(int argc, char *argv[])
145 while ((opt = getopt(argc, argv, ":r:p:t:s:vf")) != -1) {
148 threads = atoi(optarg);
149 pr_debug("Testing with (%d) threads\n", threads);
152 fsize = atoi(optarg);
153 pr_debug("size: %lu Bytes\n", fsize);
160 ratio_ptr = strtok(ratio, ",");
161 if (ratio_ptr[0] == '1') {
166 if (ratio_ptr != NULL)
167 file_ratio[0] = strtod(ratio_ptr, NULL);
168 ratio_ptr = strtok(NULL, ",");
169 if (ratio_ptr != NULL)
170 file_ratio[1] = strtod(ratio_ptr, NULL);
173 use_fallocate = true;
184 /* Sanity test of parameters */
187 assert(file_ratio[0]);
188 assert(file_ratio[1]);
190 pr_debug("Testing with (%d) threads\n", threads);
191 pr_debug("size: %lu Bytes\n", fsize);