]>
Commit | Line | Data |
---|---|---|
2bd0ea18 | 1 | /* |
da23017d NS |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | |
dfc130f3 | 4 | * |
da23017d NS |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | |
2bd0ea18 | 7 | * published by the Free Software Foundation. |
dfc130f3 | 8 | * |
da23017d NS |
9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
dfc130f3 | 13 | * |
da23017d NS |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
2bd0ea18 NS |
17 | */ |
18 | ||
dfc130f3 | 19 | /* |
2bd0ea18 NS |
20 | * Make file utility for xfs. |
21 | */ | |
22 | ||
1d7e80ee | 23 | #include <xfs/libxfs.h> |
2bd0ea18 | 24 | #include <ctype.h> |
2bd0ea18 | 25 | |
2bd0ea18 NS |
26 | #define MAXBUFFERSIZE (256 * 1024) |
27 | ||
66c016f3 | 28 | char *progname; |
2bd0ea18 | 29 | |
14290264 NS |
30 | static void |
31 | usage(void) | |
32 | { | |
9440d84d NS |
33 | fprintf(stderr, _("%s: [-npv] <size> <name1> [<name2>] ...\n"), |
34 | progname); | |
14290264 NS |
35 | exit(2); |
36 | } | |
37 | ||
38 | static int | |
39 | openfd(char *name, int oflags) | |
40 | { | |
14290264 NS |
41 | int fd; |
42 | ||
43 | fd = open(name, oflags, 0600); | |
44 | if (fd < 0) { | |
45 | perror(name); | |
46 | return -1; | |
47 | } | |
48 | ||
93d9f139 | 49 | if (!platform_test_xfs_fd(fd)) { |
9440d84d NS |
50 | fprintf(stderr, _("%s: " |
51 | "file [\"%s\"] is not on an XFS filesystem\n"), | |
14290264 NS |
52 | progname, name); |
53 | return -1; | |
54 | } | |
55 | return fd; | |
56 | } | |
57 | ||
2bd0ea18 NS |
58 | int |
59 | main(int argc, char **argv) | |
60 | { | |
61 | int fd; | |
93d9f139 | 62 | char *fname; |
2bd0ea18 NS |
63 | loff_t result; |
64 | loff_t size = 0; | |
65 | loff_t mult = 0; | |
66 | int bytes = 0; | |
67 | loff_t wrote = 0; | |
68 | int len = 0; | |
69 | int c; | |
70 | int errflg = 0; | |
71 | int errs = 0; | |
72 | int nobytes = 0; | |
73 | int prealloc = 0; | |
74 | int verbose = 0; | |
75 | struct dioattr da; | |
2bd0ea18 NS |
76 | void *buf = NULL; |
77 | int buflen = 0, nbuflen; | |
78 | int bufalign = 0, nbufalign, bufmin; | |
79 | int oflags; | |
80 | xfs_flock64_t flck; | |
81 | ||
82 | progname = basename(argv[0]); | |
9440d84d NS |
83 | setlocale(LC_ALL, ""); |
84 | bindtextdomain(PACKAGE, LOCALEDIR); | |
85 | textdomain(PACKAGE); | |
86 | ||
2bd0ea18 NS |
87 | while ((c = getopt(argc, argv, "npvV")) != EOF) { |
88 | switch(c) { | |
89 | case 'n': | |
90 | nobytes++; | |
91 | break; | |
92 | case 'p': | |
93 | prealloc++; | |
94 | break; | |
95 | case 'v': | |
96 | verbose++; | |
97 | break; | |
98 | case 'V': | |
9440d84d | 99 | printf(_("%s version %s\n"), progname, VERSION); |
3d98fe63 | 100 | exit(0); |
2bd0ea18 NS |
101 | default: |
102 | errflg++; | |
103 | break; | |
104 | } | |
105 | } | |
106 | ||
107 | if (argc < optind + 2 || errflg) | |
108 | usage(); | |
109 | ||
110 | mult = 1; | |
111 | ||
112 | len = strlen(argv[optind]); | |
113 | ||
93d9f139 NS |
114 | if (isalpha((int)argv[optind][len-1])) { |
115 | switch ((int)argv[optind][len-1]) { | |
2bd0ea18 NS |
116 | case 'k': |
117 | case 'K': | |
118 | mult = 1024; | |
119 | break; | |
120 | case 'b': | |
121 | case 'B': | |
122 | mult = 512; | |
123 | break; | |
124 | case 'm': | |
125 | case 'M': | |
126 | mult = 1024; | |
127 | mult *= 1024; | |
128 | break; | |
129 | case 'g': | |
130 | case 'G': | |
131 | mult = 1024; | |
132 | mult *= 1024; | |
133 | mult *= 1024; | |
134 | break; | |
135 | default: | |
9440d84d | 136 | fprintf(stderr, _("unknown size %s\n"), argv[optind]); |
2bd0ea18 NS |
137 | usage(); |
138 | } | |
139 | ||
140 | argv[optind][len-1] = '\0'; | |
141 | } | |
142 | ||
6bef826c | 143 | size = strtoll(argv[optind], NULL, 10) * mult; |
2bd0ea18 NS |
144 | |
145 | optind++; | |
146 | ||
147 | while (optind < argc) { | |
148 | if (verbose) | |
9440d84d | 149 | fprintf(stdout, _("%s %lld bytes %s\n"), |
5b64e00a | 150 | argv[optind], (long long)size, |
2bd0ea18 | 151 | prealloc |
9440d84d | 152 | ? _("(pre-allocated)") |
2bd0ea18 NS |
153 | : ""); |
154 | ||
155 | oflags = O_CREAT|O_TRUNC|O_WRONLY|(nobytes ? 0 : O_DIRECT); | |
93d9f139 | 156 | fname = argv[optind]; |
2bd0ea18 | 157 | |
93d9f139 | 158 | if ((fd = openfd(fname, oflags)) == -1) { |
14290264 NS |
159 | optind++; |
160 | errs++; | |
161 | continue; | |
162 | } | |
2bd0ea18 NS |
163 | |
164 | if ( (oflags & O_DIRECT) | |
165 | && ( (fd < 0 && errno == EINVAL) | |
93d9f139 | 166 | || xfsctl(fname, fd, XFS_IOC_DIOINFO, &da) < 0)) { |
2bd0ea18 NS |
167 | |
168 | close(fd); | |
169 | ||
170 | oflags &= ~O_DIRECT; | |
171 | ||
14290264 NS |
172 | if ((fd = openfd(argv[optind], oflags)) == -1) { |
173 | optind++; | |
174 | errs++; | |
175 | continue; | |
176 | } | |
2bd0ea18 NS |
177 | } |
178 | ||
179 | if (size == 0) { | |
180 | close(fd); | |
181 | optind++; | |
182 | continue; | |
183 | } | |
184 | ||
185 | if ((result = lseek64(fd, size - 1, SEEK_SET)) < 0LL) { | |
9440d84d | 186 | fprintf(stderr, _("lseek64 error, result = %lld\n"), |
5b64e00a | 187 | (long long)result); |
2bd0ea18 NS |
188 | if (errno) |
189 | perror(argv[optind]); | |
190 | errs++; | |
191 | } else if (nobytes) { | |
192 | if (write(fd, "", 1) < 0) { | |
193 | perror(argv[optind]); | |
194 | errs++; | |
195 | } | |
196 | } else { | |
197 | flck.l_whence = SEEK_SET; | |
198 | flck.l_start = 0LL; | |
199 | flck.l_len = size; | |
30b0c726 | 200 | if (prealloc) |
93d9f139 | 201 | xfsctl(fname, fd, XFS_IOC_RESVSP64, &flck); |
2bd0ea18 NS |
202 | if (oflags & O_DIRECT) { |
203 | nbufalign = da.d_mem; | |
204 | ||
205 | if ( da.d_miniosz <= MAXBUFFERSIZE | |
206 | && MAXBUFFERSIZE <= da.d_maxiosz) | |
207 | nbuflen = MAXBUFFERSIZE; | |
208 | else if (da.d_maxiosz < MAXBUFFERSIZE) | |
209 | nbuflen = da.d_maxiosz; | |
210 | else | |
211 | nbuflen = da.d_miniosz; | |
212 | ||
213 | bufmin = da.d_miniosz; | |
214 | } else { | |
215 | nbuflen = MAXBUFFERSIZE; | |
216 | nbufalign = sizeof(long); | |
217 | bufmin = 0; | |
218 | } | |
219 | ||
220 | if (nbuflen > buflen || nbufalign > bufalign) { | |
221 | if (buf) | |
222 | free(buf); | |
223 | buf = memalign(nbufalign, nbuflen); | |
224 | buflen = nbuflen; | |
225 | bzero(buf, nbuflen); | |
226 | nbufalign = bufalign; | |
227 | } | |
228 | ||
229 | wrote = 0; | |
230 | ||
231 | lseek64(fd, 0LL, SEEK_SET); | |
232 | ||
233 | while (wrote < size) { | |
234 | if (size - wrote >= buflen) | |
235 | bytes = buflen; | |
236 | else if (bufmin) | |
237 | bytes = roundup(size - wrote, bufmin); | |
238 | else | |
239 | bytes = size - wrote; | |
240 | ||
241 | len = write(fd, buf, bytes); | |
242 | ||
243 | if (len < 0) { | |
244 | perror(argv[optind]); | |
245 | unlink(argv[optind]); | |
246 | errs++; | |
247 | break; | |
248 | } | |
249 | ||
250 | wrote += len; | |
251 | } | |
252 | ||
253 | if (wrote > size && ftruncate64(fd, size) < 0) { | |
254 | perror(argv[optind]); | |
255 | unlink(argv[optind]); | |
256 | errs++; | |
257 | } | |
258 | } | |
259 | ||
260 | if ( close(fd) < 0 ) { | |
261 | perror(argv[optind]); | |
262 | unlink(argv[optind]); | |
263 | errs++; | |
264 | } | |
265 | ||
266 | optind++; | |
267 | } | |
268 | ||
269 | return errs != 0; | |
270 | } |