]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - mkfile/xfs_mkfile.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / mkfile / xfs_mkfile.c
CommitLineData
2bd0ea18 1/*
93d9f139 2 * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
dfc130f3 3 *
2bd0ea18
NS
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.
dfc130f3 7 *
2bd0ea18
NS
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.
dfc130f3 11 *
2bd0ea18
NS
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.
dfc130f3 18 *
2bd0ea18
NS
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.
dfc130f3 22 *
2bd0ea18
NS
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
dfc130f3
RC
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
2bd0ea18
NS
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
dfc130f3 33/*
2bd0ea18
NS
34 * Make file utility for xfs.
35 */
36
f91dde66 37#include <libxfs.h>
2bd0ea18 38#include <ctype.h>
2bd0ea18 39
2bd0ea18
NS
40#define MAXBUFFERSIZE (256 * 1024)
41
37cb1ae1 42static char *progname;
2bd0ea18 43
14290264
NS
44static void
45usage(void)
46{
9440d84d
NS
47 fprintf(stderr, _("%s: [-npv] <size> <name1> [<name2>] ...\n"),
48 progname);
14290264
NS
49 exit(2);
50}
51
52static int
53openfd(char *name, int oflags)
54{
14290264
NS
55 int fd;
56
57 fd = open(name, oflags, 0600);
58 if (fd < 0) {
59 perror(name);
60 return -1;
61 }
62
93d9f139 63 if (!platform_test_xfs_fd(fd)) {
9440d84d
NS
64 fprintf(stderr, _("%s: "
65 "file [\"%s\"] is not on an XFS filesystem\n"),
14290264
NS
66 progname, name);
67 return -1;
68 }
69 return fd;
70}
71
2bd0ea18
NS
72int
73main(int argc, char **argv)
74{
75 int fd;
93d9f139 76 char *fname;
2bd0ea18
NS
77 loff_t result;
78 loff_t size = 0;
79 loff_t mult = 0;
80 int bytes = 0;
81 loff_t wrote = 0;
82 int len = 0;
83 int c;
84 int errflg = 0;
85 int errs = 0;
86 int nobytes = 0;
87 int prealloc = 0;
88 int verbose = 0;
89 struct dioattr da;
2bd0ea18
NS
90 void *buf = NULL;
91 int buflen = 0, nbuflen;
92 int bufalign = 0, nbufalign, bufmin;
93 int oflags;
94 xfs_flock64_t flck;
95
96 progname = basename(argv[0]);
9440d84d
NS
97 setlocale(LC_ALL, "");
98 bindtextdomain(PACKAGE, LOCALEDIR);
99 textdomain(PACKAGE);
100
2bd0ea18
NS
101 while ((c = getopt(argc, argv, "npvV")) != EOF) {
102 switch(c) {
103 case 'n':
104 nobytes++;
105 break;
106 case 'p':
107 prealloc++;
108 break;
109 case 'v':
110 verbose++;
111 break;
112 case 'V':
9440d84d 113 printf(_("%s version %s\n"), progname, VERSION);
3d98fe63 114 exit(0);
2bd0ea18
NS
115 default:
116 errflg++;
117 break;
118 }
119 }
120
121 if (argc < optind + 2 || errflg)
122 usage();
123
124 mult = 1;
125
126 len = strlen(argv[optind]);
127
93d9f139
NS
128 if (isalpha((int)argv[optind][len-1])) {
129 switch ((int)argv[optind][len-1]) {
2bd0ea18
NS
130 case 'k':
131 case 'K':
132 mult = 1024;
133 break;
134 case 'b':
135 case 'B':
136 mult = 512;
137 break;
138 case 'm':
139 case 'M':
140 mult = 1024;
141 mult *= 1024;
142 break;
143 case 'g':
144 case 'G':
145 mult = 1024;
146 mult *= 1024;
147 mult *= 1024;
148 break;
149 default:
9440d84d 150 fprintf(stderr, _("unknown size %s\n"), argv[optind]);
2bd0ea18
NS
151 usage();
152 }
153
154 argv[optind][len-1] = '\0';
155 }
156
6bef826c 157 size = strtoll(argv[optind], NULL, 10) * mult;
2bd0ea18
NS
158
159 optind++;
160
161 while (optind < argc) {
162 if (verbose)
9440d84d 163 fprintf(stdout, _("%s %lld bytes %s\n"),
5b64e00a 164 argv[optind], (long long)size,
2bd0ea18 165 prealloc
9440d84d 166 ? _("(pre-allocated)")
2bd0ea18
NS
167 : "");
168
169 oflags = O_CREAT|O_TRUNC|O_WRONLY|(nobytes ? 0 : O_DIRECT);
93d9f139 170 fname = argv[optind];
2bd0ea18 171
93d9f139 172 if ((fd = openfd(fname, oflags)) == -1) {
14290264
NS
173 optind++;
174 errs++;
175 continue;
176 }
2bd0ea18
NS
177
178 if ( (oflags & O_DIRECT)
179 && ( (fd < 0 && errno == EINVAL)
93d9f139 180 || xfsctl(fname, fd, XFS_IOC_DIOINFO, &da) < 0)) {
2bd0ea18
NS
181
182 close(fd);
183
184 oflags &= ~O_DIRECT;
185
14290264
NS
186 if ((fd = openfd(argv[optind], oflags)) == -1) {
187 optind++;
188 errs++;
189 continue;
190 }
2bd0ea18
NS
191 }
192
193 if (size == 0) {
194 close(fd);
195 optind++;
196 continue;
197 }
198
199 if ((result = lseek64(fd, size - 1, SEEK_SET)) < 0LL) {
9440d84d 200 fprintf(stderr, _("lseek64 error, result = %lld\n"),
5b64e00a 201 (long long)result);
2bd0ea18
NS
202 if (errno)
203 perror(argv[optind]);
204 errs++;
205 } else if (nobytes) {
206 if (write(fd, "", 1) < 0) {
207 perror(argv[optind]);
208 errs++;
209 }
210 } else {
211 flck.l_whence = SEEK_SET;
212 flck.l_start = 0LL;
213 flck.l_len = size;
30b0c726 214 if (prealloc)
93d9f139 215 xfsctl(fname, fd, XFS_IOC_RESVSP64, &flck);
2bd0ea18
NS
216 if (oflags & O_DIRECT) {
217 nbufalign = da.d_mem;
218
219 if ( da.d_miniosz <= MAXBUFFERSIZE
220 && MAXBUFFERSIZE <= da.d_maxiosz)
221 nbuflen = MAXBUFFERSIZE;
222 else if (da.d_maxiosz < MAXBUFFERSIZE)
223 nbuflen = da.d_maxiosz;
224 else
225 nbuflen = da.d_miniosz;
226
227 bufmin = da.d_miniosz;
228 } else {
229 nbuflen = MAXBUFFERSIZE;
230 nbufalign = sizeof(long);
231 bufmin = 0;
232 }
233
234 if (nbuflen > buflen || nbufalign > bufalign) {
235 if (buf)
236 free(buf);
237 buf = memalign(nbufalign, nbuflen);
238 buflen = nbuflen;
239 bzero(buf, nbuflen);
240 nbufalign = bufalign;
241 }
242
243 wrote = 0;
244
245 lseek64(fd, 0LL, SEEK_SET);
246
247 while (wrote < size) {
248 if (size - wrote >= buflen)
249 bytes = buflen;
250 else if (bufmin)
251 bytes = roundup(size - wrote, bufmin);
252 else
253 bytes = size - wrote;
254
255 len = write(fd, buf, bytes);
256
257 if (len < 0) {
258 perror(argv[optind]);
259 unlink(argv[optind]);
260 errs++;
261 break;
262 }
263
264 wrote += len;
265 }
266
267 if (wrote > size && ftruncate64(fd, size) < 0) {
268 perror(argv[optind]);
269 unlink(argv[optind]);
270 errs++;
271 }
272 }
273
274 if ( close(fd) < 0 ) {
275 perror(argv[optind]);
276 unlink(argv[optind]);
277 errs++;
278 }
279
280 optind++;
281 }
282
283 return errs != 0;
284}