]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/open.c
Merge branch 'progs-cleanup' into for-next
[thirdparty/xfsprogs-dev.git] / io / open.c
1 /*
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
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
7 * published by the Free Software Foundation.
8 *
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.
13 *
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
17 */
18
19 #include "xfs/xfs.h"
20 #include "xfs/command.h"
21 #include "xfs/input.h"
22 #include "init.h"
23 #include "io.h"
24
25 #ifndef __O_TMPFILE
26 #if defined __alpha__
27 #define __O_TMPFILE 0100000000
28 #elif defined(__hppa__)
29 #define __O_TMPFILE 040000000
30 #elif defined(__sparc__)
31 #define __O_TMPFILE 0x2000000
32 #else
33 #define __O_TMPFILE 020000000
34 #endif
35 #endif /* __O_TMPFILE */
36
37 #ifndef O_TMPFILE
38 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
39 #endif
40
41 static cmdinfo_t open_cmd;
42 static cmdinfo_t stat_cmd;
43 static cmdinfo_t close_cmd;
44 static cmdinfo_t statfs_cmd;
45 static cmdinfo_t chproj_cmd;
46 static cmdinfo_t lsproj_cmd;
47 static cmdinfo_t extsize_cmd;
48 static prid_t prid;
49 static long extsize;
50
51 off64_t
52 filesize(void)
53 {
54 struct stat64 st;
55
56 if (fstat64(file->fd, &st) < 0) {
57 perror("fstat64");
58 return -1;
59 }
60 return st.st_size;
61 }
62
63 static char *
64 filetype(mode_t mode)
65 {
66 switch (mode & S_IFMT) {
67 case S_IFSOCK:
68 return _("socket");
69 case S_IFDIR:
70 return _("directory");
71 case S_IFCHR:
72 return _("char device");
73 case S_IFBLK:
74 return _("block device");
75 case S_IFREG:
76 return _("regular file");
77 case S_IFLNK:
78 return _("symbolic link");
79 case S_IFIFO:
80 return _("fifo");
81 }
82 return NULL;
83 }
84
85 static int
86 stat_f(
87 int argc,
88 char **argv)
89 {
90 struct dioattr dio;
91 struct fsxattr fsx, fsxa;
92 struct stat64 st;
93 int verbose = (argc == 2 && !strcmp(argv[1], "-v"));
94
95 printf(_("fd.path = \"%s\"\n"), file->name);
96 printf(_("fd.flags = %s,%s,%s%s%s%s%s\n"),
97 file->flags & IO_OSYNC ? _("sync") : _("non-sync"),
98 file->flags & IO_DIRECT ? _("direct") : _("non-direct"),
99 file->flags & IO_READONLY ? _("read-only") : _("read-write"),
100 file->flags & IO_REALTIME ? _(",real-time") : "",
101 file->flags & IO_APPEND ? _(",append-only") : "",
102 file->flags & IO_NONBLOCK ? _(",non-block") : "",
103 file->flags & IO_TMPFILE ? _(",tmpfile") : "");
104 if (fstat64(file->fd, &st) < 0) {
105 perror("fstat64");
106 } else {
107 printf(_("stat.ino = %lld\n"), (long long)st.st_ino);
108 printf(_("stat.type = %s\n"), filetype(st.st_mode));
109 printf(_("stat.size = %lld\n"), (long long)st.st_size);
110 printf(_("stat.blocks = %lld\n"), (long long)st.st_blocks);
111 if (verbose) {
112 printf(_("stat.atime = %s"), ctime(&st.st_atime));
113 printf(_("stat.mtime = %s"), ctime(&st.st_mtime));
114 printf(_("stat.ctime = %s"), ctime(&st.st_ctime));
115 }
116 }
117 if (file->flags & IO_FOREIGN)
118 return 0;
119 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0 ||
120 (xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTRA, &fsxa)) < 0) {
121 perror("XFS_IOC_FSGETXATTR");
122 } else {
123 printf(_("fsxattr.xflags = 0x%x "), fsx.fsx_xflags);
124 printxattr(fsx.fsx_xflags, verbose, 0, file->name, 1, 1);
125 printf(_("fsxattr.projid = %u\n"), fsx.fsx_projid);
126 printf(_("fsxattr.extsize = %u\n"), fsx.fsx_extsize);
127 printf(_("fsxattr.nextents = %u\n"), fsx.fsx_nextents);
128 printf(_("fsxattr.naextents = %u\n"), fsxa.fsx_nextents);
129 }
130 if ((xfsctl(file->name, file->fd, XFS_IOC_DIOINFO, &dio)) < 0) {
131 perror("XFS_IOC_DIOINFO");
132 } else {
133 printf(_("dioattr.mem = 0x%x\n"), dio.d_mem);
134 printf(_("dioattr.miniosz = %u\n"), dio.d_miniosz);
135 printf(_("dioattr.maxiosz = %u\n"), dio.d_maxiosz);
136 }
137 return 0;
138 }
139
140 int
141 openfile(
142 char *path,
143 xfs_fsop_geom_t *geom,
144 int flags,
145 mode_t mode)
146 {
147 int fd;
148 int oflags;
149
150 oflags = flags & IO_READONLY ? O_RDONLY : O_RDWR;
151 if (flags & IO_APPEND)
152 oflags |= O_APPEND;
153 if (flags & IO_CREAT)
154 oflags |= O_CREAT;
155 if (flags & IO_DIRECT)
156 oflags |= O_DIRECT;
157 if (flags & IO_OSYNC)
158 oflags |= O_SYNC;
159 if (flags & IO_TRUNC)
160 oflags |= O_TRUNC;
161 if (flags & IO_NONBLOCK)
162 oflags |= O_NONBLOCK;
163 if (flags & IO_TMPFILE)
164 oflags |= O_TMPFILE;
165
166 fd = open(path, oflags, mode);
167 if (fd < 0) {
168 if (errno == EISDIR &&
169 ((oflags & (O_RDWR|O_TMPFILE)) == O_RDWR)) {
170 /* make it as if we asked for O_RDONLY & try again */
171 oflags &= ~O_RDWR;
172 oflags |= O_RDONLY;
173 flags |= IO_READONLY;
174 fd = open(path, oflags, mode);
175 if (fd < 0) {
176 perror(path);
177 return -1;
178 }
179 } else {
180 perror(path);
181 return -1;
182 }
183 }
184
185 if (!geom || !platform_test_xfs_fd(fd))
186 return fd;
187
188 if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
189 perror("XFS_IOC_FSGEOMETRY");
190 close(fd);
191 return -1;
192 }
193
194 if (!(flags & IO_READONLY) && (flags & IO_REALTIME)) {
195 struct fsxattr attr;
196
197 if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &attr) < 0) {
198 perror("XFS_IOC_FSGETXATTR");
199 close(fd);
200 return -1;
201 }
202 if (!(attr.fsx_xflags & XFS_XFLAG_REALTIME)) {
203 attr.fsx_xflags |= XFS_XFLAG_REALTIME;
204 if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &attr) < 0) {
205 perror("XFS_IOC_FSSETXATTR");
206 close(fd);
207 return -1;
208 }
209 }
210 }
211 return fd;
212 }
213
214 int
215 addfile(
216 char *name,
217 int fd,
218 xfs_fsop_geom_t *geometry,
219 int flags)
220 {
221 char *filename;
222
223 filename = strdup(name);
224 if (!filename) {
225 perror("strdup");
226 close(fd);
227 return -1;
228 }
229
230 /* Extend the table of currently open files */
231 filetable = (fileio_t *)realloc(filetable, /* growing */
232 ++filecount * sizeof(fileio_t));
233 if (!filetable) {
234 perror("realloc");
235 filecount = 0;
236 free(filename);
237 close(fd);
238 return -1;
239 }
240
241 /* Finally, make this the new active open file */
242 file = &filetable[filecount - 1];
243 file->fd = fd;
244 file->flags = flags;
245 file->name = filename;
246 file->geom = *geometry;
247 return 0;
248 }
249
250 static void
251 open_help(void)
252 {
253 printf(_(
254 "\n"
255 " opens a new file in the requested mode\n"
256 "\n"
257 " Example:\n"
258 " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n"
259 "\n"
260 " Opens a file for subsequent use by all of the other xfs_io commands.\n"
261 " With no arguments, open uses the stat command to show the current file.\n"
262 " -a -- open with the O_APPEND flag (append-only mode)\n"
263 " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n"
264 " -f -- open with O_CREAT (create the file if it doesn't exist)\n"
265 " -m -- permissions to use in case a new file is created (default 0600)\n"
266 " -n -- open with O_NONBLOCK\n"
267 " -r -- open with O_RDONLY, the default is O_RDWR\n"
268 " -s -- open with O_SYNC\n"
269 " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n"
270 " -R -- mark the file as a realtime XFS file immediately after opening it\n"
271 " -T -- open with O_TMPFILE (create a file not visible in the namespace)\n"
272 " Note1: usually read/write direct IO requests must be blocksize aligned;\n"
273 " some kernels, however, allow sectorsize alignment for direct IO.\n"
274 " Note2: the bmap for non-regular files can be obtained provided the file\n"
275 " was opened correctly (in particular, must be opened read-only).\n"
276 "\n"));
277 }
278
279 static int
280 open_f(
281 int argc,
282 char **argv)
283 {
284 int c, fd, flags = 0;
285 char *sp;
286 mode_t mode = 0600;
287 xfs_fsop_geom_t geometry = { 0 };
288
289 if (argc == 1) {
290 if (file)
291 return stat_f(argc, argv);
292 fprintf(stderr, _("no files are open, try 'help open'\n"));
293 return 0;
294 }
295
296 while ((c = getopt(argc, argv, "FRTacdfm:nrstx")) != EOF) {
297 switch (c) {
298 case 'F':
299 /* Ignored / deprecated now, handled automatically */
300 break;
301 case 'a':
302 flags |= IO_APPEND;
303 break;
304 case 'c':
305 case 'f':
306 flags |= IO_CREAT;
307 break;
308 case 'd':
309 flags |= IO_DIRECT;
310 break;
311 case 'm':
312 mode = strtoul(optarg, &sp, 0);
313 if (!sp || sp == optarg) {
314 printf(_("non-numeric mode -- %s\n"), optarg);
315 return 0;
316 }
317 break;
318 case 'n':
319 flags |= IO_NONBLOCK;
320 break;
321 case 'r':
322 flags |= IO_READONLY;
323 break;
324 case 's':
325 flags |= IO_OSYNC;
326 break;
327 case 't':
328 flags |= IO_TRUNC;
329 break;
330 case 'R':
331 case 'x': /* backwards compatibility */
332 flags |= IO_REALTIME;
333 break;
334 case 'T':
335 flags |= IO_TMPFILE;
336 break;
337 default:
338 return command_usage(&open_cmd);
339 }
340 }
341
342 if (optind != argc - 1)
343 return command_usage(&open_cmd);
344
345 if ((flags & (IO_READONLY|IO_TMPFILE)) == (IO_READONLY|IO_TMPFILE)) {
346 fprintf(stderr, _("-T and -r options are incompatible\n"));
347 return -1;
348 }
349
350 fd = openfile(argv[optind], &geometry, flags, mode);
351 if (fd < 0)
352 return 0;
353
354 if (!platform_test_xfs_fd(fd))
355 flags |= IO_FOREIGN;
356
357 addfile(argv[optind], fd, &geometry, flags);
358 return 0;
359 }
360
361 static int
362 close_f(
363 int argc,
364 char **argv)
365 {
366 size_t length;
367 unsigned int offset;
368
369 if (close(file->fd) < 0) {
370 perror("close");
371 return 0;
372 }
373 free(file->name);
374
375 /* Shuffle the file table entries down over the removed entry */
376 offset = file - &filetable[0];
377 length = filecount * sizeof(fileio_t);
378 length -= (offset + 1) * sizeof(fileio_t);
379 if (length)
380 memmove(file, file + 1, length);
381
382 /* Resize the memory allocated for the table, possibly freeing */
383 if (--filecount) {
384 filetable = (fileio_t *)realloc(filetable, /* shrinking */
385 filecount * sizeof(fileio_t));
386 if (offset == filecount)
387 offset--;
388 file = filetable + offset;
389 } else {
390 free(filetable);
391 file = filetable = NULL;
392 }
393 filelist_f();
394 return 0;
395 }
396
397 static void
398 lsproj_help(void)
399 {
400 printf(_(
401 "\n"
402 " displays the project identifier associated with the current path\n"
403 "\n"
404 " Options:\n"
405 " -R -- recursively descend (useful when current path is a directory)\n"
406 " -D -- recursively descend, but only list projects on directories\n"
407 "\n"));
408 }
409
410 static int
411 lsproj_callback(
412 const char *path,
413 const struct stat *stat,
414 int status,
415 struct FTW *data)
416 {
417 prid_t projid;
418 int fd;
419
420 if (recurse_dir && !S_ISDIR(stat->st_mode))
421 return 0;
422
423 if ((fd = open(path, O_RDONLY)) == -1) {
424 fprintf(stderr, _("%s: cannot open %s: %s\n"),
425 progname, path, strerror(errno));
426 } else {
427 if (getprojid(path, fd, &projid) == 0)
428 printf("[%u] %s\n", (unsigned int)projid, path);
429 close(fd);
430 }
431 return 0;
432 }
433
434 static int
435 lsproj_f(
436 int argc,
437 char **argv)
438 {
439 prid_t projid;
440 int c;
441
442 recurse_all = recurse_dir = 0;
443 while ((c = getopt(argc, argv, "DR")) != EOF) {
444 switch (c) {
445 case 'D':
446 recurse_all = 0;
447 recurse_dir = 1;
448 break;
449 case 'R':
450 recurse_all = 1;
451 recurse_dir = 0;
452 break;
453 default:
454 return command_usage(&lsproj_cmd);
455 }
456 }
457
458 if (argc != optind)
459 return command_usage(&lsproj_cmd);
460
461 if (recurse_all || recurse_dir)
462 nftw(file->name, lsproj_callback,
463 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
464 else if (getprojid(file->name, file->fd, &projid) < 0)
465 perror("getprojid");
466 else
467 printf(_("projid = %u\n"), (unsigned int)projid);
468 return 0;
469 }
470
471 static void
472 chproj_help(void)
473 {
474 printf(_(
475 "\n"
476 " modifies the project identifier associated with the current path\n"
477 "\n"
478 " -R -- recursively descend (useful when current path is a directory)\n"
479 " -D -- recursively descend, only modifying projects on directories\n"
480 "\n"));
481 }
482
483 static int
484 chproj_callback(
485 const char *path,
486 const struct stat *stat,
487 int status,
488 struct FTW *data)
489 {
490 int fd;
491
492 if (recurse_dir && !S_ISDIR(stat->st_mode))
493 return 0;
494
495 if ((fd = open(path, O_RDONLY)) == -1) {
496 fprintf(stderr, _("%s: cannot open %s: %s\n"),
497 progname, path, strerror(errno));
498 } else {
499 if (setprojid(path, fd, prid) < 0)
500 perror("setprojid");
501 close(fd);
502 }
503 return 0;
504 }
505
506 static int
507 chproj_f(
508 int argc,
509 char **argv)
510 {
511 int c;
512
513 recurse_all = recurse_dir = 0;
514 while ((c = getopt(argc, argv, "DR")) != EOF) {
515 switch (c) {
516 case 'D':
517 recurse_all = 0;
518 recurse_dir = 1;
519 break;
520 case 'R':
521 recurse_all = 1;
522 recurse_dir = 0;
523 break;
524 default:
525 return command_usage(&chproj_cmd);
526 }
527 }
528
529 if (argc != optind + 1)
530 return command_usage(&chproj_cmd);
531
532 prid = prid_from_string(argv[optind]);
533 if (prid == -1) {
534 printf(_("invalid project ID -- %s\n"), argv[optind]);
535 return 0;
536 }
537
538 if (recurse_all || recurse_dir)
539 nftw(file->name, chproj_callback,
540 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
541 else if (setprojid(file->name, file->fd, prid) < 0)
542 perror("setprojid");
543 return 0;
544 }
545
546 static void
547 extsize_help(void)
548 {
549 printf(_(
550 "\n"
551 " report or modify preferred extent size (in bytes) for the current path\n"
552 "\n"
553 " -R -- recursively descend (useful when current path is a directory)\n"
554 " -D -- recursively descend, only modifying extsize on directories\n"
555 "\n"));
556 }
557
558 static int
559 get_extsize(const char *path, int fd)
560 {
561 struct fsxattr fsx;
562
563 if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
564 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
565 progname, path, strerror(errno));
566 return 0;
567 }
568 printf("[%u] %s\n", fsx.fsx_extsize, path);
569 return 0;
570 }
571
572 static int
573 set_extsize(const char *path, int fd, long extsz)
574 {
575 struct fsxattr fsx;
576 struct stat64 stat;
577
578 if (fstat64(fd, &stat) < 0) {
579 perror("fstat64");
580 return 0;
581 }
582 if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
583 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
584 progname, path, strerror(errno));
585 return 0;
586 }
587
588 if (S_ISREG(stat.st_mode)) {
589 fsx.fsx_xflags |= XFS_XFLAG_EXTSIZE;
590 } else if (S_ISDIR(stat.st_mode)) {
591 fsx.fsx_xflags |= XFS_XFLAG_EXTSZINHERIT;
592 } else {
593 printf(_("invalid target file type - file %s\n"), path);
594 return 0;
595 }
596 fsx.fsx_extsize = extsz;
597
598 if ((xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx)) < 0) {
599 printf("%s: XFS_IOC_FSSETXATTR %s: %s\n",
600 progname, path, strerror(errno));
601 return 0;
602 }
603
604 return 0;
605 }
606
607 static int
608 get_extsize_callback(
609 const char *path,
610 const struct stat *stat,
611 int status,
612 struct FTW *data)
613 {
614 int fd;
615
616 if (recurse_dir && !S_ISDIR(stat->st_mode))
617 return 0;
618
619 if ((fd = open(path, O_RDONLY)) == -1) {
620 fprintf(stderr, _("%s: cannot open %s: %s\n"),
621 progname, path, strerror(errno));
622 } else {
623 get_extsize(path, fd);
624 close(fd);
625 }
626 return 0;
627 }
628
629 static int
630 set_extsize_callback(
631 const char *path,
632 const struct stat *stat,
633 int status,
634 struct FTW *data)
635 {
636 int fd;
637
638 if (recurse_dir && !S_ISDIR(stat->st_mode))
639 return 0;
640
641 if ((fd = open(path, O_RDONLY)) == -1) {
642 fprintf(stderr, _("%s: cannot open %s: %s\n"),
643 progname, path, strerror(errno));
644 } else {
645 set_extsize(path, fd, extsize);
646 close(fd);
647 }
648 return 0;
649 }
650
651 static int
652 extsize_f(
653 int argc,
654 char **argv)
655 {
656 size_t blocksize, sectsize;
657 int c;
658
659 recurse_all = recurse_dir = 0;
660 init_cvtnum(&blocksize, &sectsize);
661 while ((c = getopt(argc, argv, "DR")) != EOF) {
662 switch (c) {
663 case 'D':
664 recurse_all = 0;
665 recurse_dir = 1;
666 break;
667 case 'R':
668 recurse_all = 1;
669 recurse_dir = 0;
670 break;
671 default:
672 return command_usage(&extsize_cmd);
673 }
674 }
675
676 if (optind < argc) {
677 extsize = (long)cvtnum(blocksize, sectsize, argv[optind]);
678 if (extsize < 0) {
679 printf(_("non-numeric extsize argument -- %s\n"),
680 argv[optind]);
681 return 0;
682 }
683 } else {
684 extsize = -1;
685 }
686
687 if (recurse_all || recurse_dir)
688 nftw(file->name, (extsize >= 0) ?
689 set_extsize_callback : get_extsize_callback,
690 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
691 else if (extsize >= 0)
692 set_extsize(file->name, file->fd, extsize);
693 else
694 get_extsize(file->name, file->fd);
695 return 0;
696 }
697
698 static int
699 statfs_f(
700 int argc,
701 char **argv)
702 {
703 struct xfs_fsop_counts fscounts;
704 struct xfs_fsop_geom fsgeo;
705 struct statfs st;
706
707 printf(_("fd.path = \"%s\"\n"), file->name);
708 if (platform_fstatfs(file->fd, &st) < 0) {
709 perror("fstatfs");
710 } else {
711 printf(_("statfs.f_bsize = %lld\n"), (long long) st.f_bsize);
712 printf(_("statfs.f_blocks = %lld\n"), (long long) st.f_blocks);
713 #if defined(__sgi__)
714 printf(_("statfs.f_frsize = %lld\n"), (long long) st.f_frsize);
715 #else
716 printf(_("statfs.f_bavail = %lld\n"), (long long) st.f_bavail);
717 #endif
718 printf(_("statfs.f_files = %lld\n"), (long long) st.f_files);
719 printf(_("statfs.f_ffree = %lld\n"), (long long) st.f_ffree);
720 }
721 if (file->flags & IO_FOREIGN)
722 return 0;
723 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
724 perror("XFS_IOC_FSGEOMETRY_V1");
725 } else {
726 printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
727 printf(_("geom.agcount = %u\n"), fsgeo.agcount);
728 printf(_("geom.agblocks = %u\n"), fsgeo.agblocks);
729 printf(_("geom.datablocks = %llu\n"),
730 (unsigned long long) fsgeo.datablocks);
731 printf(_("geom.rtblocks = %llu\n"),
732 (unsigned long long) fsgeo.rtblocks);
733 printf(_("geom.rtextents = %llu\n"),
734 (unsigned long long) fsgeo.rtextents);
735 printf(_("geom.rtextsize = %u\n"), fsgeo.rtextsize);
736 printf(_("geom.sunit = %u\n"), fsgeo.sunit);
737 printf(_("geom.swidth = %u\n"), fsgeo.swidth);
738 }
739 if ((xfsctl(file->name, file->fd, XFS_IOC_FSCOUNTS, &fscounts)) < 0) {
740 perror("XFS_IOC_FSCOUNTS");
741 } else {
742 printf(_("counts.freedata = %llu\n"),
743 (unsigned long long) fscounts.freedata);
744 printf(_("counts.freertx = %llu\n"),
745 (unsigned long long) fscounts.freertx);
746 printf(_("counts.freeino = %llu\n"),
747 (unsigned long long) fscounts.freeino);
748 printf(_("counts.allocino = %llu\n"),
749 (unsigned long long) fscounts.allocino);
750 }
751 return 0;
752 }
753
754 void
755 open_init(void)
756 {
757 open_cmd.name = "open";
758 open_cmd.altname = "o";
759 open_cmd.cfunc = open_f;
760 open_cmd.argmin = 0;
761 open_cmd.argmax = -1;
762 open_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK;
763 open_cmd.args = _("[-acdrstxT] [path]");
764 open_cmd.oneline = _("open the file specified by path");
765 open_cmd.help = open_help;
766
767 stat_cmd.name = "stat";
768 stat_cmd.cfunc = stat_f;
769 stat_cmd.argmin = 0;
770 stat_cmd.argmax = 1;
771 stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
772 stat_cmd.args = _("[-v]");
773 stat_cmd.oneline = _("statistics on the currently open file");
774
775 close_cmd.name = "close";
776 close_cmd.altname = "c";
777 close_cmd.cfunc = close_f;
778 close_cmd.argmin = 0;
779 close_cmd.argmax = 0;
780 close_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
781 close_cmd.oneline = _("close the current open file");
782
783 statfs_cmd.name = "statfs";
784 statfs_cmd.cfunc = statfs_f;
785 statfs_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
786 statfs_cmd.oneline =
787 _("statistics on the filesystem of the currently open file");
788
789 chproj_cmd.name = "chproj";
790 chproj_cmd.cfunc = chproj_f;
791 chproj_cmd.args = _("[-D | -R] projid");
792 chproj_cmd.argmin = 1;
793 chproj_cmd.argmax = -1;
794 chproj_cmd.flags = CMD_NOMAP_OK;
795 chproj_cmd.oneline =
796 _("change project identifier on the currently open file");
797 chproj_cmd.help = chproj_help;
798
799 lsproj_cmd.name = "lsproj";
800 lsproj_cmd.cfunc = lsproj_f;
801 lsproj_cmd.args = _("[-D | -R]");
802 lsproj_cmd.argmin = 0;
803 lsproj_cmd.argmax = -1;
804 lsproj_cmd.flags = CMD_NOMAP_OK;
805 lsproj_cmd.oneline =
806 _("list project identifier set on the currently open file");
807 lsproj_cmd.help = lsproj_help;
808
809 extsize_cmd.name = "extsize";
810 extsize_cmd.cfunc = extsize_f;
811 extsize_cmd.args = _("[-D | -R] [extsize]");
812 extsize_cmd.argmin = 0;
813 extsize_cmd.argmax = -1;
814 extsize_cmd.flags = CMD_NOMAP_OK;
815 extsize_cmd.oneline =
816 _("get/set preferred extent size (in bytes) for the open file");
817 extsize_cmd.help = extsize_help;
818
819 add_command(&open_cmd);
820 add_command(&stat_cmd);
821 add_command(&close_cmd);
822 add_command(&statfs_cmd);
823 add_command(&chproj_cmd);
824 add_command(&lsproj_cmd);
825 add_command(&extsize_cmd);
826 }