xref: /haiku/src/tests/add-ons/kernel/file_systems/shared/fragmenter.cpp (revision b8a45b3a2df2379b4301bf3bd5949b9a105be4ba)
1 /*
2  * Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <getopt.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 #include <OS.h>
17 
18 
19 extern const char* __progname;
20 const char* kProgramName = __progname;
21 
22 const int32_t kDefaultFiles = -1;
23 const off_t kDefaultFileSize = 4096;
24 
25 
26 static void
27 usage(int status)
28 {
29 	printf("usage: %s [--files <num-of-files>] [--size <file-size>]\n",
30 		kProgramName);
31 	printf("options:\n");
32 	printf("  -f  --files  Number of files to be created. Defaults to as "
33 		"many as fit.\n");
34 	printf("  -s  --size   Size of each file. Defaults to %lldKB.\n",
35 		kDefaultFileSize / 1024);
36 
37 	exit(status);
38 }
39 
40 
41 static bool
42 create_file(int32_t i, const char* suffix, const char* buffer, size_t size)
43 {
44 	char name[64];
45 	snprintf(name, sizeof(name), "fragments/%06d%s", i, suffix);
46 
47 	int fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644);
48 	if (fd < 0) {
49 		fprintf(stderr, "%s: Could not create file %d: %s\n", kProgramName,
50 			i, strerror(errno));
51 		return false;
52 	}
53 
54 	if (write(fd, buffer, size) < (ssize_t)size) {
55 		fprintf(stderr, "%s: Could not write file %d: %s\n", kProgramName,
56 			i, strerror(errno));
57 		return false;
58 	}
59 
60 	close(fd);
61 	return true;
62 }
63 
64 
65 int
66 main(int argc, char** argv)
67 {
68 	int32_t numFiles = kDefaultFiles;
69 	off_t fileSize = kDefaultFileSize;
70 
71 	int optionIndex = 0;
72 	int opt;
73 	static struct option longOptions[] = {
74 		{"help", no_argument, 0, 'h'},
75 		{"size", required_argument, 0, 's'},
76 		{"files", required_argument, 0, 'f'},
77 		{0, 0, 0, 0}
78 	};
79 
80 	do {
81 		opt = getopt_long(argc, argv, "hs:f:", longOptions, &optionIndex);
82 		switch (opt) {
83 			case -1:
84 				// end of arguments, do nothing
85 				break;
86 
87 			case 'f':
88 				numFiles = strtoul(optarg, NULL, 0);
89 				break;
90 
91 			case 's':
92 				fileSize = strtoul(optarg, NULL, 0);
93 				break;
94 
95 			case 'h':
96 			default:
97 				usage(0);
98 				break;
99 		}
100 	} while (opt != -1);
101 
102 	// fill buffer
103 
104 	char* buffer = (char*)malloc(fileSize);
105 	if (buffer == NULL) {
106 		fprintf(stderr, "%s: not enough memory.\n", kProgramName);
107 		exit(1);
108 	}
109 
110 	for (uint32_t i = 0; i < fileSize; i++) {
111 		buffer[i] = (char)(i & 0xff);
112 	}
113 
114 	// create files
115 
116 	if (numFiles > 0)
117 		printf("Creating %d files...\n", numFiles);
118 	else
119 		printf("Creating as many files as fit...\n");
120 
121 	mkdir("fragments", 0777);
122 
123 	int32_t filesCreated = 0;
124 	bigtime_t lastTime = 0;
125 
126 	for (int32_t i = 0; i < numFiles || numFiles < 0; i++) {
127 		if (!create_file(i, "", buffer, fileSize)
128 			|| !create_file(i, ".remove", buffer, fileSize))
129 			break;
130 
131 		filesCreated++;
132 
133 		if (lastTime + 250000LL < system_time()) {
134 			printf("%10d\33[1A\n", filesCreated);
135 			lastTime = system_time();
136 		}
137 	}
138 
139 	free(buffer);
140 
141 	// delete fragmentation files
142 
143 	printf("Deleting %d temporary files...\n", filesCreated);
144 
145 	for (int32_t i = 0; i < filesCreated; i++) {
146 		char name[64];
147 		snprintf(name, sizeof(name), "fragments/%06d.remove", i);
148 
149 		if (remove(name) != 0) {
150 			fprintf(stderr, "%s: Could not remove file %d: %s\n",
151 				kProgramName, i, strerror(errno));
152 		}
153 
154 		if (lastTime + 250000LL < system_time()) {
155 			printf("%10d\33[1A\n", i);
156 			lastTime = system_time();
157 		}
158 	}
159 
160 	printf("          \33[1A\n");
161 		// delete progress count
162 
163 	return 0;
164 }
165