]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - mkfile/xfs_mkfile.c
bump minor version number.
[thirdparty/xfsprogs-dev.git] / mkfile / xfs_mkfile.c
1 /*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 /*
34 * Make file utility for xfs.
35 */
36
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/ioctl.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <ctype.h>
43 #include <malloc.h>
44 #include <errno.h>
45 #include <libxfs.h>
46
47 #define MAXBUFFERSIZE (256 * 1024)
48
49 static void usage(void);
50 static char *progname;
51
52 int
53 main(int argc, char **argv)
54 {
55 int fd;
56 loff_t result;
57 loff_t size = 0;
58 loff_t mult = 0;
59 int bytes = 0;
60 loff_t wrote = 0;
61 int len = 0;
62 int c;
63 int errflg = 0;
64 int errs = 0;
65 int nobytes = 0;
66 int prealloc = 0;
67 int verbose = 0;
68 struct dioattr da;
69 void *buf = NULL;
70 int buflen = 0, nbuflen;
71 int bufalign = 0, nbufalign, bufmin;
72 int oflags;
73 xfs_flock64_t flck;
74
75 progname = basename(argv[0]);
76 while ((c = getopt(argc, argv, "npvV")) != EOF) {
77 switch(c) {
78 case 'n':
79 nobytes++;
80 break;
81 case 'p':
82 prealloc++;
83 break;
84 case 'v':
85 verbose++;
86 break;
87 case 'V':
88 printf("%s version %s\n", progname, VERSION);
89 break;
90 default:
91 errflg++;
92 break;
93 }
94 }
95
96 if (argc < optind + 2 || errflg)
97 usage();
98
99 mult = 1;
100
101 len = strlen(argv[optind]);
102
103 if (isalpha(argv[optind][len-1])) {
104 switch (argv[optind][len-1]) {
105 case 'k':
106 case 'K':
107 mult = 1024;
108 break;
109 case 'b':
110 case 'B':
111 mult = 512;
112 break;
113 case 'm':
114 case 'M':
115 mult = 1024;
116 mult *= 1024;
117 break;
118 case 'g':
119 case 'G':
120 mult = 1024;
121 mult *= 1024;
122 mult *= 1024;
123 break;
124 default:
125 fprintf(stderr, "unknown size %s\n", argv[optind]);
126 usage();
127 }
128
129 argv[optind][len-1] = '\0';
130 }
131
132 size = atoll(argv[optind]) * mult;
133
134 optind++;
135
136 while (optind < argc) {
137 if (verbose)
138 fprintf(stdout, "%s %lld bytes %s\n",
139 argv[optind], (long long)size,
140 prealloc
141 ? "(pre-allocated)"
142 : "");
143
144 oflags = O_CREAT|O_TRUNC|O_WRONLY|(nobytes ? 0 : O_DIRECT);
145
146 fd = open(argv[optind], oflags, 0600);
147
148 if ( (oflags & O_DIRECT)
149 && ( (fd < 0 && errno == EINVAL)
150 || ioctl(fd, XFS_IOC_DIOINFO, &da) < 0)) {
151
152 close(fd);
153
154 oflags &= ~O_DIRECT;
155
156 fd = open(argv[optind], oflags, 0600);
157 }
158
159 if (fd < 0) {
160 perror(argv[optind]);
161 optind++;
162 errs++;
163 continue;
164 }
165
166 if (size == 0) {
167 close(fd);
168 optind++;
169 continue;
170 }
171
172 if ((result = lseek64(fd, size - 1, SEEK_SET)) < 0LL) {
173 /*
174 * This check doesn't actually work for 6.2
175 * efs and nfs2, although it should.
176 */
177 fprintf(stderr, "lseek64 error, result = %lld\n",
178 (long long)result);
179 if (errno)
180 perror(argv[optind]);
181 errs++;
182 } else if (nobytes) {
183 if (write(fd, "", 1) < 0) {
184 perror(argv[optind]);
185 errs++;
186 }
187 } else {
188 flck.l_whence = SEEK_SET;
189 flck.l_start = 0LL;
190 flck.l_len = size;
191 #if 0
192 (void)ioctl(fd, XFS_IOC_RESVSP64, &flck);
193
194 if (prealloc) {
195 if ( close(fd) < 0 ) {
196 perror(argv[optind]);
197 unlink(argv[optind]);
198 errs++;
199 }
200
201 optind++;
202
203 continue;
204 }
205 #endif
206 if (oflags & O_DIRECT) {
207 nbufalign = da.d_mem;
208
209 if ( da.d_miniosz <= MAXBUFFERSIZE
210 && MAXBUFFERSIZE <= da.d_maxiosz)
211 nbuflen = MAXBUFFERSIZE;
212 else if (da.d_maxiosz < MAXBUFFERSIZE)
213 nbuflen = da.d_maxiosz;
214 else
215 nbuflen = da.d_miniosz;
216
217 bufmin = da.d_miniosz;
218 } else {
219 nbuflen = MAXBUFFERSIZE;
220 nbufalign = sizeof(long);
221 bufmin = 0;
222 }
223
224 if (nbuflen > buflen || nbufalign > bufalign) {
225 if (buf)
226 free(buf);
227 buf = memalign(nbufalign, nbuflen);
228 buflen = nbuflen;
229 bzero(buf, nbuflen);
230 nbufalign = bufalign;
231 }
232
233 wrote = 0;
234
235 lseek64(fd, 0LL, SEEK_SET);
236
237 while (wrote < size) {
238 if (size - wrote >= buflen)
239 bytes = buflen;
240 else if (bufmin)
241 bytes = roundup(size - wrote, bufmin);
242 else
243 bytes = size - wrote;
244
245 len = write(fd, buf, bytes);
246
247 if (len < 0) {
248 perror(argv[optind]);
249 unlink(argv[optind]);
250 errs++;
251 break;
252 }
253
254 wrote += len;
255 }
256
257 if (wrote > size && ftruncate64(fd, size) < 0) {
258 perror(argv[optind]);
259 unlink(argv[optind]);
260 errs++;
261 }
262 }
263
264 if ( close(fd) < 0 ) {
265 perror(argv[optind]);
266 unlink(argv[optind]);
267 errs++;
268 }
269
270 optind++;
271 }
272
273 return errs != 0;
274 }
275
276 static void
277 usage(void)
278 {
279 fprintf(stderr, "%s: [-npv] <size> <name1> [<name2>] ...\n", progname);
280 exit(2);
281 }