]>
Commit | Line | Data |
---|---|---|
e246ba5f NS |
1 | /* |
2 | * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. | |
dfc130f3 | 3 | * |
e246ba5f 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 | * |
e246ba5f 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 | * |
e246ba5f 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 | * |
e246ba5f 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 | * |
e246ba5f 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 | * | |
e246ba5f NS |
30 | * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ |
31 | */ | |
dfc130f3 | 32 | |
e246ba5f NS |
33 | #include <libxfs.h> |
34 | #include "command.h" | |
35 | #include "init.h" | |
36 | ||
37 | static cmdinfo_t open_cmd; | |
38 | static cmdinfo_t stat_cmd; | |
39 | static cmdinfo_t statfs_cmd; | |
40 | static int stat_f(int, char **); | |
41 | ||
42 | int | |
43 | openfile( | |
93d9f139 | 44 | char *path, |
e246ba5f NS |
45 | int aflag, |
46 | int cflag, | |
47 | int dflag, | |
48 | int rflag, | |
49 | int sflag, | |
50 | int tflag, | |
51 | int xflag) | |
52 | { | |
53 | int fd; | |
54 | int oflags; | |
e246ba5f NS |
55 | |
56 | oflags = (rflag ? O_RDONLY : O_RDWR); | |
57 | if (aflag) | |
58 | oflags |= O_APPEND; | |
59 | if (cflag) | |
60 | oflags |= O_CREAT; | |
61 | if (dflag) | |
62 | oflags |= O_DIRECT; | |
63 | if (sflag) | |
64 | oflags |= O_SYNC; | |
65 | if (tflag) | |
66 | oflags |= O_TRUNC; | |
67 | ||
93d9f139 | 68 | fd = open(path, oflags, 0644); |
e246ba5f | 69 | if (fd < 0) { |
93d9f139 | 70 | perror(path); |
e246ba5f NS |
71 | return -1; |
72 | } | |
93d9f139 | 73 | if (!platform_test_xfs_fd(fd)) { |
e246ba5f NS |
74 | fprintf(stderr, _("%s: specified file " |
75 | "[\"%s\"] is not on an XFS filesystem\n"), | |
76 | progname, fname); | |
77 | close(fd); | |
78 | return -1; | |
79 | } | |
80 | ||
81 | if (!readonly && xflag) { /* read/write and realtime */ | |
82 | struct fsxattr attr; | |
83 | ||
93d9f139 | 84 | if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &attr) < 0) { |
e246ba5f NS |
85 | perror("XFS_IOC_FSGETXATTR"); |
86 | close(fd); | |
87 | return -1; | |
88 | } | |
89 | if (!(attr.fsx_xflags & XFS_XFLAG_REALTIME)) { | |
90 | attr.fsx_xflags |= XFS_XFLAG_REALTIME; | |
93d9f139 | 91 | if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &attr) < 0) { |
e246ba5f NS |
92 | perror("XFS_IOC_FSSETXATTR"); |
93 | close(fd); | |
94 | return -1; | |
95 | } | |
96 | } | |
97 | } | |
98 | return fd; | |
99 | } | |
100 | ||
101 | static int | |
102 | usage(void) | |
103 | { | |
104 | printf("%s %s\n", open_cmd.name, open_cmd.oneline); | |
105 | return 0; | |
106 | } | |
107 | ||
108 | static void | |
109 | open_help(void) | |
110 | { | |
111 | printf(_( | |
112 | "\n" | |
113 | " opens a new file in the requested mode, after closing the current file\n" | |
114 | "\n" | |
115 | " Example:\n" | |
116 | " 'open -d /tmp/data' - opens data file read-write for direct IO\n" | |
117 | "\n" | |
118 | " Opens a file for subsequent use by all of the other xfs_io commands.\n" | |
119 | " With no arguments, open uses the stat command to show the current file.\n" | |
120 | " -a -- open with the O_APPEND flag (append-only mode)\n" | |
121 | " -c -- open with O_CREAT (create the file if it doesn't exist)\n" | |
122 | " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n" | |
123 | " -r -- open with O_RDONLY, the default is O_RDWR\n" | |
124 | " -s -- open with O_SYNC\n" | |
125 | " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n" | |
126 | " -x -- mark the file as a realtime XFS file immediately after opening it\n" | |
127 | " Note1: read/write direct IO requests must be blocksize aligned.\n" | |
128 | " Note2: the bmap for non-regular files can be obtained provided the file\n" | |
129 | " was opened appropriately (in particular, must be opened read-only).\n" | |
130 | "\n")); | |
131 | } | |
132 | ||
133 | static int | |
134 | open_f( | |
135 | int argc, | |
136 | char **argv) | |
137 | { | |
138 | int aflag = 0; | |
139 | int cflag = 0; | |
140 | int dflag = 0; | |
141 | int rflag = 0; | |
142 | int sflag = 0; | |
143 | int tflag = 0; | |
144 | int xflag = 0; | |
145 | char *filename; | |
146 | int fd; | |
147 | int c; | |
148 | ||
149 | if (argc == 1) | |
150 | return stat_f(argc, argv); | |
151 | ||
152 | while ((c = getopt(argc, argv, "acdrstx")) != EOF) { | |
153 | switch (c) { | |
154 | case 'a': | |
155 | aflag = 1; | |
156 | break; | |
157 | case 'c': | |
158 | cflag = 1; | |
159 | break; | |
160 | case 'd': | |
161 | dflag = 1; | |
162 | break; | |
163 | case 'r': | |
164 | rflag = 1; | |
165 | break; | |
166 | case 's': | |
167 | sflag = 1; | |
168 | break; | |
169 | case 't': | |
170 | tflag = 1; | |
171 | break; | |
172 | case 'x': | |
173 | xflag = 1; | |
174 | break; | |
175 | default: | |
176 | return usage(); | |
177 | } | |
178 | } | |
179 | ||
180 | if (optind != argc - 1) | |
181 | return usage(); | |
182 | ||
183 | fd = openfile(argv[optind], | |
184 | aflag, cflag, dflag, rflag, sflag, tflag, xflag); | |
185 | if (fd < 0) | |
186 | return 0; | |
187 | ||
188 | filename = strdup(argv[optind]); | |
189 | if (!filename) { | |
190 | perror("strdup"); | |
191 | close(fd); | |
192 | return 0; | |
193 | } | |
194 | ||
195 | /* | |
196 | * All OK, proceed to make this the new global open file | |
197 | */ | |
198 | osync = sflag; | |
199 | trunc = tflag; | |
200 | append = aflag; | |
201 | directio = dflag; | |
202 | readonly = rflag; | |
203 | realtime = xflag; | |
204 | if (fname) { | |
205 | close(fdesc); | |
206 | free(fname); | |
207 | } | |
208 | fname = filename; | |
209 | fdesc = fd; | |
210 | return 0; | |
211 | } | |
212 | ||
213 | off64_t | |
214 | filesize(void) | |
215 | { | |
216 | struct stat64 st; | |
217 | ||
218 | if (fstat64(fdesc, &st) < 0) { | |
219 | perror("fstat64"); | |
220 | return -1; | |
221 | } | |
222 | return st.st_size; | |
223 | } | |
224 | ||
225 | static char * | |
226 | filetype(mode_t mode) | |
227 | { | |
228 | switch (mode & S_IFMT) { | |
229 | case S_IFSOCK: | |
230 | return _("socket"); | |
231 | case S_IFDIR: | |
232 | return _("directory"); | |
233 | case S_IFCHR: | |
234 | return _("char device"); | |
235 | case S_IFBLK: | |
236 | return _("block device"); | |
237 | case S_IFREG: | |
238 | return _("regular file"); | |
239 | case S_IFLNK: | |
240 | return _("symbolic link"); | |
241 | case S_IFIFO: | |
242 | return _("fifo"); | |
243 | } | |
244 | return NULL; | |
245 | } | |
246 | ||
247 | static int | |
248 | stat_f( | |
249 | int argc, | |
250 | char **argv) | |
251 | { | |
252 | struct fsxattr fsx; | |
253 | struct stat64 st; | |
254 | char fullname[PATH_MAX + 1]; | |
255 | ||
256 | printf(_("fd.path = \"%s\"\n"), | |
257 | realpath(fname, fullname) ? fullname : fname); | |
258 | printf(_("fd.flags = %s,%s,%s%s%s\n"), | |
259 | osync ? _("sync") : _("non-sync"), | |
260 | directio ? _("direct") : _("non-direct"), | |
261 | readonly ? _("read-only") : _("read-write"), | |
262 | realtime ? _(",real-time") : "", | |
263 | append ? _(",append-only") : ""); | |
264 | if (fstat64(fdesc, &st) < 0) { | |
265 | perror("fstat64"); | |
266 | } else { | |
267 | printf(_("stat.ino = %lld\n"), (long long)st.st_ino); | |
268 | printf(_("stat.type = %s\n"), filetype(st.st_mode)); | |
269 | printf(_("stat.size = %lld\n"), (long long)st.st_size); | |
270 | printf(_("stat.blocks = %lld\n"), (long long)st.st_blocks); | |
271 | if (argc == 2 && !strcmp(argv[1], "-v")) { | |
272 | printf(_("stat.atime = %s"), ctime(&st.st_atime)); | |
273 | printf(_("stat.mtime = %s"), ctime(&st.st_mtime)); | |
274 | printf(_("stat.ctime = %s"), ctime(&st.st_ctime)); | |
275 | } | |
276 | } | |
93d9f139 NS |
277 | if ((xfsctl(fname, fdesc, XFS_IOC_FSGETXATTR, &fsx)) < 0) { |
278 | perror("xfsctl(XFS_IOC_FSGETXATTR)"); | |
e246ba5f NS |
279 | } else { |
280 | printf(_("xattr.xflags = 0x%x\n"), fsx.fsx_xflags); | |
281 | printf(_("xattr.nextents = %u\n"), fsx.fsx_nextents); | |
282 | } | |
283 | return 0; | |
284 | } | |
285 | ||
286 | static int | |
287 | statfs_f( | |
288 | int argc, | |
289 | char **argv) | |
290 | { | |
291 | struct xfs_fsop_geom_v1 fsgeo; | |
292 | struct statfs st; | |
293 | char fullname[PATH_MAX + 1]; | |
294 | ||
295 | printf(_("fd.path = \"%s\"\n"), | |
296 | realpath(fname, fullname) ? fullname : fname); | |
93d9f139 | 297 | if (platform_fstatfs(fdesc, &st) < 0) { |
e246ba5f NS |
298 | perror("fstatfs"); |
299 | } else { | |
300 | printf(_("statfs.f_bsize = %lld\n"), (long long) st.f_bsize); | |
301 | printf(_("statfs.f_blocks = %lld\n"), (long long) st.f_blocks); | |
93d9f139 | 302 | #if !defined(__sgi__) |
e246ba5f | 303 | printf(_("statfs.f_bavail = %lld\n"), (long long) st.f_bavail); |
93d9f139 | 304 | #endif |
e246ba5f | 305 | } |
93d9f139 NS |
306 | if ((xfsctl(fname, fdesc, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) { |
307 | perror("xfsctl(XFS_IOC_FSGEOMETRY_V1)"); | |
e246ba5f NS |
308 | } else { |
309 | printf(_("geom.bsize = %u\n"), fsgeo.blocksize); | |
310 | printf(_("geom.agcount = %u\n"), fsgeo.agcount); | |
311 | printf(_("geom.agblocks = %u\n"), fsgeo.agblocks); | |
312 | printf(_("geom.datablocks = %llu\n"), | |
313 | (unsigned long long) fsgeo.datablocks); | |
314 | printf(_("geom.rtblocks = %llu\n"), | |
315 | (unsigned long long) fsgeo.rtblocks); | |
316 | printf(_("geom.rtextents = %llu\n"), | |
317 | (unsigned long long) fsgeo.rtextents); | |
318 | printf(_("geom.rtextsize = %u\n"), fsgeo.rtextsize); | |
319 | printf(_("geom.sunit = %u\n"), fsgeo.sunit); | |
320 | printf(_("geom.swidth = %u\n"), fsgeo.swidth); | |
321 | } | |
322 | return 0; | |
323 | } | |
324 | ||
325 | void | |
326 | open_init(void) | |
327 | { | |
328 | open_cmd.name = _("open"); | |
329 | open_cmd.altname = _("o"); | |
330 | open_cmd.cfunc = open_f; | |
331 | open_cmd.argmin = 0; | |
332 | open_cmd.argmax = -1; | |
333 | open_cmd.args = _("[-acdrstx] [path]"); | |
334 | open_cmd.oneline = | |
335 | _("close the current file, open file specified by path"); | |
336 | open_cmd.help = open_help; | |
337 | ||
338 | stat_cmd.name = _("stat"); | |
339 | stat_cmd.cfunc = stat_f; | |
340 | stat_cmd.argmin = 0; | |
341 | stat_cmd.argmax = 1; | |
342 | stat_cmd.args = _("[-v]"); | |
343 | stat_cmd.oneline = | |
344 | _("statistics on the currently open file"); | |
345 | ||
346 | statfs_cmd.name = _("statfs"); | |
347 | statfs_cmd.cfunc = statfs_f; | |
348 | statfs_cmd.oneline = | |
349 | _("statistics on the filesystem of the currently open file"); | |
350 | ||
351 | add_command(&open_cmd); | |
352 | add_command(&stat_cmd); | |
353 | add_command(&statfs_cmd); | |
354 | } |