]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/open.c
Merge whitespace changes over
[thirdparty/xfsprogs-dev.git] / io / open.c
1 /*
2 * Copyright (c) 2003 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 #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(
44 char *path,
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;
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
68 fd = open(path, oflags, 0644);
69 if (fd < 0) {
70 perror(path);
71 return -1;
72 }
73 if (!platform_test_xfs_fd(fd)) {
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
84 if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &attr) < 0) {
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;
91 if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &attr) < 0) {
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 }
277 if ((xfsctl(fname, fdesc, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
278 perror("xfsctl(XFS_IOC_FSGETXATTR)");
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);
297 if (platform_fstatfs(fdesc, &st) < 0) {
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);
302 #if !defined(__sgi__)
303 printf(_("statfs.f_bavail = %lld\n"), (long long) st.f_bavail);
304 #endif
305 }
306 if ((xfsctl(fname, fdesc, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
307 perror("xfsctl(XFS_IOC_FSGEOMETRY_V1)");
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 }