]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - mkfile/xfs_mkfile.c
Merge of xfs-cmds-2.4.18:slinx:111135a by nathans.
[thirdparty/xfsprogs-dev.git] / mkfile / xfs_mkfile.c
CommitLineData
2bd0ea18
NS
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
f91dde66
NS
37#include <libxfs.h>
38#include <malloc.h>
2bd0ea18 39#include <sys/stat.h>
f91dde66 40#include <sys/ioctl.h>
14290264 41#include <sys/vfs.h>
2bd0ea18 42#include <ctype.h>
2bd0ea18 43
2bd0ea18
NS
44#define MAXBUFFERSIZE (256 * 1024)
45
37cb1ae1 46static char *progname;
2bd0ea18 47
14290264
NS
48static void
49usage(void)
50{
51 fprintf(stderr, "%s: [-npv] <size> <name1> [<name2>] ...\n", progname);
52 exit(2);
53}
54
55static int
56openfd(char *name, int oflags)
57{
58 struct statfs buf;
59 int fd;
60
61 fd = open(name, oflags, 0600);
62 if (fd < 0) {
63 perror(name);
64 return -1;
65 }
66
67 fstatfs(fd, &buf);
68 if (buf.f_type != XFS_SUPER_MAGIC) {
69 fprintf(stderr, "%s: "
70 "file [\"%s\"] is not on an XFS filesystem\n",
71 progname, name);
72 return -1;
73 }
74 return fd;
75}
76
2bd0ea18
NS
77int
78main(int argc, char **argv)
79{
80 int fd;
81 loff_t result;
82 loff_t size = 0;
83 loff_t mult = 0;
84 int bytes = 0;
85 loff_t wrote = 0;
86 int len = 0;
87 int c;
88 int errflg = 0;
89 int errs = 0;
90 int nobytes = 0;
91 int prealloc = 0;
92 int verbose = 0;
93 struct dioattr da;
2bd0ea18
NS
94 void *buf = NULL;
95 int buflen = 0, nbuflen;
96 int bufalign = 0, nbufalign, bufmin;
97 int oflags;
98 xfs_flock64_t flck;
99
100 progname = basename(argv[0]);
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':
113 printf("%s version %s\n", progname, VERSION);
114 break;
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
128 if (isalpha(argv[optind][len-1])) {
129 switch (argv[optind][len-1]) {
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:
150 fprintf(stderr, "unknown size %s\n", argv[optind]);
151 usage();
152 }
153
154 argv[optind][len-1] = '\0';
155 }
156
157 size = atoll(argv[optind]) * mult;
158
159 optind++;
160
161 while (optind < argc) {
162 if (verbose)
163 fprintf(stdout, "%s %lld bytes %s\n",
5b64e00a 164 argv[optind], (long long)size,
2bd0ea18
NS
165 prealloc
166 ? "(pre-allocated)"
167 : "");
168
169 oflags = O_CREAT|O_TRUNC|O_WRONLY|(nobytes ? 0 : O_DIRECT);
170
14290264
NS
171 if ((fd = openfd(argv[optind], oflags)) == -1) {
172 optind++;
173 errs++;
174 continue;
175 }
2bd0ea18
NS
176
177 if ( (oflags & O_DIRECT)
178 && ( (fd < 0 && errno == EINVAL)
179 || ioctl(fd, XFS_IOC_DIOINFO, &da) < 0)) {
180
181 close(fd);
182
183 oflags &= ~O_DIRECT;
184
14290264
NS
185 if ((fd = openfd(argv[optind], oflags)) == -1) {
186 optind++;
187 errs++;
188 continue;
189 }
2bd0ea18
NS
190 }
191
192 if (size == 0) {
193 close(fd);
194 optind++;
195 continue;
196 }
197
198 if ((result = lseek64(fd, size - 1, SEEK_SET)) < 0LL) {
199 /*
200 * This check doesn't actually work for 6.2
201 * efs and nfs2, although it should.
202 */
5b64e00a
NS
203 fprintf(stderr, "lseek64 error, result = %lld\n",
204 (long long)result);
2bd0ea18
NS
205 if (errno)
206 perror(argv[optind]);
207 errs++;
208 } else if (nobytes) {
209 if (write(fd, "", 1) < 0) {
210 perror(argv[optind]);
211 errs++;
212 }
213 } else {
214 flck.l_whence = SEEK_SET;
215 flck.l_start = 0LL;
216 flck.l_len = size;
30b0c726
NS
217 if (prealloc)
218 (void)ioctl(fd, XFS_IOC_RESVSP64, &flck);
2bd0ea18
NS
219 if (oflags & O_DIRECT) {
220 nbufalign = da.d_mem;
221
222 if ( da.d_miniosz <= MAXBUFFERSIZE
223 && MAXBUFFERSIZE <= da.d_maxiosz)
224 nbuflen = MAXBUFFERSIZE;
225 else if (da.d_maxiosz < MAXBUFFERSIZE)
226 nbuflen = da.d_maxiosz;
227 else
228 nbuflen = da.d_miniosz;
229
230 bufmin = da.d_miniosz;
231 } else {
232 nbuflen = MAXBUFFERSIZE;
233 nbufalign = sizeof(long);
234 bufmin = 0;
235 }
236
237 if (nbuflen > buflen || nbufalign > bufalign) {
238 if (buf)
239 free(buf);
240 buf = memalign(nbufalign, nbuflen);
241 buflen = nbuflen;
242 bzero(buf, nbuflen);
243 nbufalign = bufalign;
244 }
245
246 wrote = 0;
247
248 lseek64(fd, 0LL, SEEK_SET);
249
250 while (wrote < size) {
251 if (size - wrote >= buflen)
252 bytes = buflen;
253 else if (bufmin)
254 bytes = roundup(size - wrote, bufmin);
255 else
256 bytes = size - wrote;
257
258 len = write(fd, buf, bytes);
259
260 if (len < 0) {
261 perror(argv[optind]);
262 unlink(argv[optind]);
263 errs++;
264 break;
265 }
266
267 wrote += len;
268 }
269
270 if (wrote > size && ftruncate64(fd, size) < 0) {
271 perror(argv[optind]);
272 unlink(argv[optind]);
273 errs++;
274 }
275 }
276
277 if ( close(fd) < 0 ) {
278 perror(argv[optind]);
279 unlink(argv[optind]);
280 errs++;
281 }
282
283 optind++;
284 }
285
286 return errs != 0;
287}