]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/open.c
08425ebd432b105096bc76e219b05ee93748fb9f
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
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.
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.
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
19 #include <xfs/libxfs.h>
20 #include <xfs/command.h>
21 #include <xfs/input.h>
25 static cmdinfo_t open_cmd
;
26 static cmdinfo_t stat_cmd
;
27 static cmdinfo_t close_cmd
;
28 static cmdinfo_t setfl_cmd
;
29 static cmdinfo_t statfs_cmd
;
30 static cmdinfo_t chproj_cmd
;
31 static cmdinfo_t lsproj_cmd
;
32 static cmdinfo_t extsize_cmd
;
40 if (fstat64(file
->fd
, &st
) < 0) {
50 switch (mode
& S_IFMT
) {
54 return _("directory");
56 return _("char device");
58 return _("block device");
60 return _("regular file");
62 return _("symbolic link");
76 int verbose
= (argc
== 2 && !strcmp(argv
[1], "-v"));
78 printf(_("fd.path = \"%s\"\n"), file
->name
);
79 printf(_("fd.flags = %s,%s,%s%s%s%s\n"),
80 file
->flags
& IO_OSYNC
? _("sync") : _("non-sync"),
81 file
->flags
& IO_DIRECT
? _("direct") : _("non-direct"),
82 file
->flags
& IO_READONLY
? _("read-only") : _("read-write"),
83 file
->flags
& IO_REALTIME
? _(",real-time") : "",
84 file
->flags
& IO_APPEND
? _(",append-only") : "",
85 file
->flags
& IO_NONBLOCK
? _(",non-block") : "");
86 if (fstat64(file
->fd
, &st
) < 0) {
89 printf(_("stat.ino = %lld\n"), (long long)st
.st_ino
);
90 printf(_("stat.type = %s\n"), filetype(st
.st_mode
));
91 printf(_("stat.size = %lld\n"), (long long)st
.st_size
);
92 printf(_("stat.blocks = %lld\n"), (long long)st
.st_blocks
);
94 printf(_("stat.atime = %s"), ctime(&st
.st_atime
));
95 printf(_("stat.mtime = %s"), ctime(&st
.st_mtime
));
96 printf(_("stat.ctime = %s"), ctime(&st
.st_ctime
));
99 if (file
->flags
& IO_FOREIGN
)
101 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSGETXATTR
, &fsx
)) < 0) {
102 perror("XFS_IOC_FSGETXATTR");
104 printf(_("xattr.xflags = 0x%x "), fsx
.fsx_xflags
);
105 printxattr(fsx
.fsx_xflags
, verbose
, 0, file
->name
, 1, 1);
106 printf(_("xattr.extsize = %u\n"), fsx
.fsx_extsize
);
107 printf(_("xattr.nextents = %u\n"), fsx
.fsx_nextents
);
115 xfs_fsop_geom_t
*geom
,
122 oflags
= flags
& IO_READONLY
? O_RDONLY
: O_RDWR
;
123 if (flags
& IO_APPEND
)
125 if (flags
& IO_CREAT
)
127 if (flags
& IO_DIRECT
)
129 if (flags
& IO_OSYNC
)
131 if (flags
& IO_TRUNC
)
133 if (flags
& IO_NONBLOCK
)
134 oflags
|= O_NONBLOCK
;
136 fd
= open(path
, oflags
, mode
);
145 if (!platform_test_xfs_fd(fd
)) {
146 fprintf(stderr
, _("%s: specified file "
147 "[\"%s\"] is not on an XFS filesystem\n"),
153 if (xfsctl(path
, fd
, XFS_IOC_FSGEOMETRY
, geom
) < 0) {
154 perror("XFS_IOC_FSGEOMETRY");
159 if (!(flags
& IO_READONLY
) && (flags
& IO_REALTIME
)) {
162 if (xfsctl(path
, fd
, XFS_IOC_FSGETXATTR
, &attr
) < 0) {
163 perror("XFS_IOC_FSGETXATTR");
167 if (!(attr
.fsx_xflags
& XFS_XFLAG_REALTIME
)) {
168 attr
.fsx_xflags
|= XFS_XFLAG_REALTIME
;
169 if (xfsctl(path
, fd
, XFS_IOC_FSSETXATTR
, &attr
) < 0) {
170 perror("XFS_IOC_FSSETXATTR");
183 xfs_fsop_geom_t
*geometry
,
188 filename
= strdup(name
);
195 /* Extend the table of currently open files */
196 filetable
= (fileio_t
*)realloc(filetable
, /* growing */
197 ++filecount
* sizeof(fileio_t
));
206 /* Finally, make this the new active open file */
207 file
= &filetable
[filecount
- 1];
210 file
->name
= filename
;
211 file
->geom
= *geometry
;
220 " opens a new file in the requested mode\n"
223 " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n"
225 " Opens a file for subsequent use by all of the other xfs_io commands.\n"
226 " With no arguments, open uses the stat command to show the current file.\n"
227 " -F -- foreign filesystem file, disallow XFS-specific commands\n"
228 " -a -- open with the O_APPEND flag (append-only mode)\n"
229 " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n"
230 " -f -- open with O_CREAT (create the file if it doesn't exist)\n"
231 " -m -- permissions to use in case a new file is created (default 0600)\n"
232 " -n -- open with O_NONBLOCK\n"
233 " -r -- open with O_RDONLY, the default is O_RDWR\n"
234 " -s -- open with O_SYNC\n"
235 " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n"
236 " -R -- mark the file as a realtime XFS file immediately after opening it\n"
237 " Note1: usually read/write direct IO requests must be blocksize aligned;\n"
238 " some kernels, however, allow sectorsize alignment for direct IO.\n"
239 " Note2: the bmap for non-regular files can be obtained provided the file\n"
240 " was opened correctly (in particular, must be opened read-only).\n"
249 int c
, fd
, flags
= 0;
252 xfs_fsop_geom_t geometry
= { 0 };
256 return stat_f(argc
, argv
);
257 fprintf(stderr
, _("no files are open, try 'help open'\n"));
261 while ((c
= getopt(argc
, argv
, "FRacdfm:nrstx")) != EOF
) {
277 mode
= strtoul(optarg
, &sp
, 0);
278 if (!sp
|| sp
== optarg
) {
279 printf(_("non-numeric mode -- %s\n"), optarg
);
284 flags
|= IO_NONBLOCK
;
287 flags
|= IO_READONLY
;
296 case 'x': /* backwards compatibility */
297 flags
|= IO_REALTIME
;
300 return command_usage(&open_cmd
);
304 if (optind
!= argc
- 1)
305 return command_usage(&open_cmd
);
307 fd
= openfile(argv
[optind
], flags
& IO_FOREIGN
?
308 NULL
: &geometry
, flags
, mode
);
312 addfile(argv
[optind
], fd
, &geometry
, flags
);
324 if (close(file
->fd
) < 0) {
330 /* Shuffle the file table entries down over the removed entry */
331 offset
= file
- &filetable
[0];
332 length
= filecount
* sizeof(fileio_t
);
333 length
-= (offset
+ 1) * sizeof(fileio_t
);
335 memmove(file
, file
+ 1, length
);
337 /* Resize the memory allocated for the table, possibly freeing */
339 filetable
= (fileio_t
*)realloc(filetable
, /* shrinking */
340 filecount
* sizeof(fileio_t
));
341 if (offset
== filecount
)
343 file
= filetable
+ offset
;
346 file
= filetable
= NULL
;
357 " displays the project identifier associated with the current path\n"
360 " -R -- recursively descend (useful when current path is a directory)\n"
361 " -D -- recursively descend, but only list projects on directories\n"
368 const struct stat
*stat
,
375 if (recurse_dir
&& !S_ISDIR(stat
->st_mode
))
378 if ((fd
= open(path
, O_RDONLY
)) == -1) {
379 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
380 progname
, path
, strerror(errno
));
382 if (getprojid(path
, fd
, &projid
) == 0)
383 printf("[%u] %s\n", projid
, path
);
397 while ((c
= getopt(argc
, argv
, "DR")) != EOF
) {
408 return command_usage(&lsproj_cmd
);
413 return command_usage(&lsproj_cmd
);
415 if (recurse_all
|| recurse_dir
)
416 nftw(file
->name
, lsproj_callback
,
417 100, FTW_PHYS
| FTW_MOUNT
| FTW_DEPTH
);
418 else if (getprojid(file
->name
, file
->fd
, &projid
) < 0)
421 printf(_("projid = %u\n"), projid
);
430 " modifies the project identifier associated with the current path\n"
432 " -R -- recursively descend (useful when current path is a directory)\n"
433 " -D -- recursively descend, only modifying projects on directories\n"
440 const struct stat
*stat
,
446 if (recurse_dir
&& !S_ISDIR(stat
->st_mode
))
449 if ((fd
= open(path
, O_RDONLY
)) == -1) {
450 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
451 progname
, path
, strerror(errno
));
453 if (setprojid(path
, fd
, prid
) < 0)
467 while ((c
= getopt(argc
, argv
, "DR")) != EOF
) {
478 return command_usage(&chproj_cmd
);
482 if (argc
!= optind
+ 1)
483 return command_usage(&chproj_cmd
);
485 prid
= prid_from_string(argv
[optind
]);
487 printf(_("invalid project ID -- %s\n"), argv
[optind
]);
491 if (recurse_all
|| recurse_dir
)
492 nftw(file
->name
, chproj_callback
,
493 100, FTW_PHYS
| FTW_MOUNT
| FTW_DEPTH
);
494 else if (setprojid(file
->name
, file
->fd
, prid
) < 0)
506 flags
= fcntl(file
->fd
, F_GETFL
, 0);
508 perror("fcntl(F_GETFL)");
512 while ((c
= getopt(argc
, argv
, "ad")) != EOF
) {
515 if (flags
& O_APPEND
)
521 if (flags
& O_DIRECT
)
527 printf(_("invalid setfl argument -- '%c'\n"), c
);
532 if (fcntl(file
->fd
, F_SETFL
, flags
) < 0)
533 perror("fcntl(F_SETFL)");
546 size_t blocksize
, sectsize
;
548 init_cvtnum(&blocksize
, §size
);
549 extsize
= (long)cvtnum(blocksize
, sectsize
, argv
[1]);
551 printf(_("non-numeric extsize argument -- %s\n"), argv
[1]);
554 if (fstat64(file
->fd
, &stat
) < 0) {
558 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSGETXATTR
, &fsx
)) < 0) {
559 perror("XFS_IOC_FSGETXATTR");
563 if (S_ISREG(stat
.st_mode
)) {
564 fsx
.fsx_xflags
|= XFS_XFLAG_EXTSIZE
;
565 } else if (S_ISDIR(stat
.st_mode
)) {
566 fsx
.fsx_xflags
|= XFS_XFLAG_EXTSZINHERIT
;
568 printf(_("invalid target file type - file %s\n"), file
->name
);
571 fsx
.fsx_extsize
= extsize
;
573 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSSETXATTR
, &fsx
)) < 0) {
574 perror("XFS_IOC_FSSETXATTR");
586 struct xfs_fsop_counts fscounts
;
587 struct xfs_fsop_geom fsgeo
;
590 printf(_("fd.path = \"%s\"\n"), file
->name
);
591 if (platform_fstatfs(file
->fd
, &st
) < 0) {
594 printf(_("statfs.f_bsize = %lld\n"), (long long) st
.f_bsize
);
595 printf(_("statfs.f_blocks = %lld\n"), (long long) st
.f_blocks
);
597 printf(_("statfs.f_frsize = %lld\n"), (long long) st
.f_frsize
);
599 printf(_("statfs.f_bavail = %lld\n"), (long long) st
.f_bavail
);
601 printf(_("statfs.f_files = %lld\n"), (long long) st
.f_files
);
602 printf(_("statfs.f_ffree = %lld\n"), (long long) st
.f_ffree
);
604 if (file
->flags
& IO_FOREIGN
)
606 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSGEOMETRY_V1
, &fsgeo
)) < 0) {
607 perror("XFS_IOC_FSGEOMETRY_V1");
609 printf(_("geom.bsize = %u\n"), fsgeo
.blocksize
);
610 printf(_("geom.agcount = %u\n"), fsgeo
.agcount
);
611 printf(_("geom.agblocks = %u\n"), fsgeo
.agblocks
);
612 printf(_("geom.datablocks = %llu\n"),
613 (unsigned long long) fsgeo
.datablocks
);
614 printf(_("geom.rtblocks = %llu\n"),
615 (unsigned long long) fsgeo
.rtblocks
);
616 printf(_("geom.rtextents = %llu\n"),
617 (unsigned long long) fsgeo
.rtextents
);
618 printf(_("geom.rtextsize = %u\n"), fsgeo
.rtextsize
);
619 printf(_("geom.sunit = %u\n"), fsgeo
.sunit
);
620 printf(_("geom.swidth = %u\n"), fsgeo
.swidth
);
622 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSCOUNTS
, &fscounts
)) < 0) {
623 perror("XFS_IOC_FSCOUNTS");
625 printf(_("counts.freedata = %llu\n"),
626 (unsigned long long) fscounts
.freedata
);
627 printf(_("counts.freertx = %llu\n"),
628 (unsigned long long) fscounts
.freertx
);
629 printf(_("counts.freeino = %llu\n"),
630 (unsigned long long) fscounts
.freeino
);
631 printf(_("counts.allocino = %llu\n"),
632 (unsigned long long) fscounts
.allocino
);
640 open_cmd
.name
= _("open");
641 open_cmd
.altname
= _("o");
642 open_cmd
.cfunc
= open_f
;
644 open_cmd
.argmax
= -1;
645 open_cmd
.flags
= CMD_NOMAP_OK
| CMD_NOFILE_OK
| CMD_FOREIGN_OK
;
646 open_cmd
.args
= _("[-acdrstx] [path]");
647 open_cmd
.oneline
= _("open the file specified by path");
648 open_cmd
.help
= open_help
;
650 stat_cmd
.name
= _("stat");
651 stat_cmd
.cfunc
= stat_f
;
654 stat_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
655 stat_cmd
.args
= _("[-v]");
656 stat_cmd
.oneline
= _("statistics on the currently open file");
658 close_cmd
.name
= _("close");
659 close_cmd
.altname
= _("c");
660 close_cmd
.cfunc
= close_f
;
661 close_cmd
.argmin
= 0;
662 close_cmd
.argmax
= 0;
663 close_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
664 close_cmd
.oneline
= _("close the current open file");
666 setfl_cmd
.name
= _("setfl");
667 setfl_cmd
.cfunc
= setfl_f
;
668 setfl_cmd
.args
= _("[-adx]");
669 setfl_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
671 _("set/clear append/direct flags on the open file");
673 statfs_cmd
.name
= _("statfs");
674 statfs_cmd
.cfunc
= statfs_f
;
675 statfs_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
677 _("statistics on the filesystem of the currently open file");
679 chproj_cmd
.name
= _("chproj");
680 chproj_cmd
.cfunc
= chproj_f
;
681 chproj_cmd
.args
= _("[-D | -R] projid");
682 chproj_cmd
.argmin
= 1;
683 chproj_cmd
.argmax
= -1;
684 chproj_cmd
.flags
= CMD_NOMAP_OK
;
686 _("change project identifier on the currently open file");
687 chproj_cmd
.help
= chproj_help
;
689 lsproj_cmd
.name
= _("lsproj");
690 lsproj_cmd
.cfunc
= lsproj_f
;
691 lsproj_cmd
.args
= _("[-D | -R]");
692 lsproj_cmd
.argmin
= 0;
693 lsproj_cmd
.argmax
= -1;
694 lsproj_cmd
.flags
= CMD_NOMAP_OK
;
696 _("list project identifier set on the currently open file");
697 lsproj_cmd
.help
= lsproj_help
;
699 extsize_cmd
.name
= _("extsize");
700 extsize_cmd
.cfunc
= extsize_f
;
701 extsize_cmd
.argmin
= 1;
702 extsize_cmd
.argmax
= 1;
703 extsize_cmd
.flags
= CMD_NOMAP_OK
;
704 extsize_cmd
.oneline
=
705 _("set prefered extent size (in bytes) for the open file");
707 add_command(&open_cmd
);
708 add_command(&stat_cmd
);
709 add_command(&close_cmd
);
710 add_command(&setfl_cmd
);
711 add_command(&statfs_cmd
);
712 add_command(&chproj_cmd
);
713 add_command(&lsproj_cmd
);
714 add_command(&extsize_cmd
);