]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/open.c
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
26 #define __O_TMPFILE 0100000000
27 #elif defined(__hppa__)
28 #define __O_TMPFILE 040000000
29 #elif defined(__sparc__)
30 #define __O_TMPFILE 0x2000000
32 #define __O_TMPFILE 020000000
34 #endif /* __O_TMPFILE */
37 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
40 static cmdinfo_t open_cmd
;
41 static cmdinfo_t stat_cmd
;
42 static cmdinfo_t close_cmd
;
43 static cmdinfo_t statfs_cmd
;
44 static cmdinfo_t chproj_cmd
;
45 static cmdinfo_t lsproj_cmd
;
46 static cmdinfo_t extsize_cmd
;
55 if (fstat64(file
->fd
, &st
) < 0) {
65 switch (mode
& S_IFMT
) {
69 return _("directory");
71 return _("char device");
73 return _("block device");
75 return _("regular file");
77 return _("symbolic link");
90 struct fsxattr fsx
, fsxa
;
92 int verbose
= (argc
== 2 && !strcmp(argv
[1], "-v"));
94 printf(_("fd.path = \"%s\"\n"), file
->name
);
95 printf(_("fd.flags = %s,%s,%s%s%s%s%s\n"),
96 file
->flags
& IO_OSYNC
? _("sync") : _("non-sync"),
97 file
->flags
& IO_DIRECT
? _("direct") : _("non-direct"),
98 file
->flags
& IO_READONLY
? _("read-only") : _("read-write"),
99 file
->flags
& IO_REALTIME
? _(",real-time") : "",
100 file
->flags
& IO_APPEND
? _(",append-only") : "",
101 file
->flags
& IO_NONBLOCK
? _(",non-block") : "",
102 file
->flags
& IO_TMPFILE
? _(",tmpfile") : "");
103 if (fstat64(file
->fd
, &st
) < 0) {
106 printf(_("stat.ino = %lld\n"), (long long)st
.st_ino
);
107 printf(_("stat.type = %s\n"), filetype(st
.st_mode
));
108 printf(_("stat.size = %lld\n"), (long long)st
.st_size
);
109 printf(_("stat.blocks = %lld\n"), (long long)st
.st_blocks
);
111 printf(_("stat.atime = %s"), ctime(&st
.st_atime
));
112 printf(_("stat.mtime = %s"), ctime(&st
.st_mtime
));
113 printf(_("stat.ctime = %s"), ctime(&st
.st_ctime
));
116 if (file
->flags
& IO_FOREIGN
)
118 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSGETXATTR
, &fsx
)) < 0 ||
119 (xfsctl(file
->name
, file
->fd
, XFS_IOC_FSGETXATTRA
, &fsxa
)) < 0) {
120 perror("XFS_IOC_FSGETXATTR");
122 printf(_("fsxattr.xflags = 0x%x "), fsx
.fsx_xflags
);
123 printxattr(fsx
.fsx_xflags
, verbose
, 0, file
->name
, 1, 1);
124 printf(_("fsxattr.projid = %u\n"), fsx
.fsx_projid
);
125 printf(_("fsxattr.extsize = %u\n"), fsx
.fsx_extsize
);
126 printf(_("fsxattr.nextents = %u\n"), fsx
.fsx_nextents
);
127 printf(_("fsxattr.naextents = %u\n"), fsxa
.fsx_nextents
);
129 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_DIOINFO
, &dio
)) < 0) {
130 perror("XFS_IOC_DIOINFO");
132 printf(_("dioattr.mem = 0x%x\n"), dio
.d_mem
);
133 printf(_("dioattr.miniosz = %u\n"), dio
.d_miniosz
);
134 printf(_("dioattr.maxiosz = %u\n"), dio
.d_maxiosz
);
142 xfs_fsop_geom_t
*geom
,
149 oflags
= flags
& IO_READONLY
? O_RDONLY
: O_RDWR
;
150 if (flags
& IO_APPEND
)
152 if (flags
& IO_CREAT
)
154 if (flags
& IO_DIRECT
)
156 if (flags
& IO_OSYNC
)
158 if (flags
& IO_TRUNC
)
160 if (flags
& IO_NONBLOCK
)
161 oflags
|= O_NONBLOCK
;
162 if (flags
& IO_TMPFILE
)
165 fd
= open(path
, oflags
, mode
);
167 if (errno
== EISDIR
&&
168 ((oflags
& (O_RDWR
|O_TMPFILE
)) == O_RDWR
)) {
169 /* make it as if we asked for O_RDONLY & try again */
172 flags
|= IO_READONLY
;
173 fd
= open(path
, oflags
, mode
);
184 if (!geom
|| !platform_test_xfs_fd(fd
))
187 if (xfsctl(path
, fd
, XFS_IOC_FSGEOMETRY
, geom
) < 0) {
188 perror("XFS_IOC_FSGEOMETRY");
193 if (!(flags
& IO_READONLY
) && (flags
& IO_REALTIME
)) {
196 if (xfsctl(path
, fd
, XFS_IOC_FSGETXATTR
, &attr
) < 0) {
197 perror("XFS_IOC_FSGETXATTR");
201 if (!(attr
.fsx_xflags
& XFS_XFLAG_REALTIME
)) {
202 attr
.fsx_xflags
|= XFS_XFLAG_REALTIME
;
203 if (xfsctl(path
, fd
, XFS_IOC_FSSETXATTR
, &attr
) < 0) {
204 perror("XFS_IOC_FSSETXATTR");
217 xfs_fsop_geom_t
*geometry
,
222 filename
= strdup(name
);
229 /* Extend the table of currently open files */
230 filetable
= (fileio_t
*)realloc(filetable
, /* growing */
231 ++filecount
* sizeof(fileio_t
));
240 /* Finally, make this the new active open file */
241 file
= &filetable
[filecount
- 1];
244 file
->name
= filename
;
245 file
->geom
= *geometry
;
254 " opens a new file in the requested mode\n"
257 " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n"
259 " Opens a file for subsequent use by all of the other xfs_io commands.\n"
260 " With no arguments, open uses the stat command to show the current file.\n"
261 " -a -- open with the O_APPEND flag (append-only mode)\n"
262 " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n"
263 " -f -- open with O_CREAT (create the file if it doesn't exist)\n"
264 " -m -- permissions to use in case a new file is created (default 0600)\n"
265 " -n -- open with O_NONBLOCK\n"
266 " -r -- open with O_RDONLY, the default is O_RDWR\n"
267 " -s -- open with O_SYNC\n"
268 " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n"
269 " -R -- mark the file as a realtime XFS file immediately after opening it\n"
270 " -T -- open with O_TMPFILE (create a file not visible in the namespace)\n"
271 " Note1: usually read/write direct IO requests must be blocksize aligned;\n"
272 " some kernels, however, allow sectorsize alignment for direct IO.\n"
273 " Note2: the bmap for non-regular files can be obtained provided the file\n"
274 " was opened correctly (in particular, must be opened read-only).\n"
283 int c
, fd
, flags
= 0;
286 xfs_fsop_geom_t geometry
= { 0 };
290 return stat_f(argc
, argv
);
291 fprintf(stderr
, _("no files are open, try 'help open'\n"));
295 while ((c
= getopt(argc
, argv
, "FRTacdfm:nrstx")) != EOF
) {
298 /* Ignored / deprecated now, handled automatically */
311 mode
= strtoul(optarg
, &sp
, 0);
312 if (!sp
|| sp
== optarg
) {
313 printf(_("non-numeric mode -- %s\n"), optarg
);
318 flags
|= IO_NONBLOCK
;
321 flags
|= IO_READONLY
;
330 case 'x': /* backwards compatibility */
331 flags
|= IO_REALTIME
;
337 return command_usage(&open_cmd
);
341 if (optind
!= argc
- 1)
342 return command_usage(&open_cmd
);
344 if ((flags
& (IO_READONLY
|IO_TMPFILE
)) == (IO_READONLY
|IO_TMPFILE
)) {
345 fprintf(stderr
, _("-T and -r options are incompatible\n"));
349 fd
= openfile(argv
[optind
], &geometry
, flags
, mode
);
353 if (!platform_test_xfs_fd(fd
))
356 addfile(argv
[optind
], fd
, &geometry
, flags
);
368 if (close(file
->fd
) < 0) {
374 /* Shuffle the file table entries down over the removed entry */
375 offset
= file
- &filetable
[0];
376 length
= filecount
* sizeof(fileio_t
);
377 length
-= (offset
+ 1) * sizeof(fileio_t
);
379 memmove(file
, file
+ 1, length
);
381 /* Resize the memory allocated for the table, possibly freeing */
383 filetable
= (fileio_t
*)realloc(filetable
, /* shrinking */
384 filecount
* sizeof(fileio_t
));
385 if (offset
== filecount
)
387 file
= filetable
+ offset
;
390 file
= filetable
= NULL
;
401 " displays the project identifier associated with the current path\n"
404 " -R -- recursively descend (useful when current path is a directory)\n"
405 " -D -- recursively descend, but only list projects on directories\n"
412 const struct stat
*stat
,
419 if (recurse_dir
&& !S_ISDIR(stat
->st_mode
))
422 if ((fd
= open(path
, O_RDONLY
)) == -1) {
423 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
424 progname
, path
, strerror(errno
));
426 if (getprojid(path
, fd
, &projid
) == 0)
427 printf("[%u] %s\n", (unsigned int)projid
, path
);
441 recurse_all
= recurse_dir
= 0;
442 while ((c
= getopt(argc
, argv
, "DR")) != EOF
) {
453 return command_usage(&lsproj_cmd
);
458 return command_usage(&lsproj_cmd
);
460 if (recurse_all
|| recurse_dir
)
461 nftw(file
->name
, lsproj_callback
,
462 100, FTW_PHYS
| FTW_MOUNT
| FTW_DEPTH
);
463 else if (getprojid(file
->name
, file
->fd
, &projid
) < 0)
466 printf(_("projid = %u\n"), (unsigned int)projid
);
475 " modifies the project identifier associated with the current path\n"
477 " -R -- recursively descend (useful when current path is a directory)\n"
478 " -D -- recursively descend, only modifying projects on directories\n"
485 const struct stat
*stat
,
491 if (recurse_dir
&& !S_ISDIR(stat
->st_mode
))
494 if ((fd
= open(path
, O_RDONLY
)) == -1) {
495 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
496 progname
, path
, strerror(errno
));
498 if (setprojid(path
, fd
, prid
) < 0)
512 recurse_all
= recurse_dir
= 0;
513 while ((c
= getopt(argc
, argv
, "DR")) != EOF
) {
524 return command_usage(&chproj_cmd
);
528 if (argc
!= optind
+ 1)
529 return command_usage(&chproj_cmd
);
531 prid
= prid_from_string(argv
[optind
]);
533 printf(_("invalid project ID -- %s\n"), argv
[optind
]);
537 if (recurse_all
|| recurse_dir
)
538 nftw(file
->name
, chproj_callback
,
539 100, FTW_PHYS
| FTW_MOUNT
| FTW_DEPTH
);
540 else if (setprojid(file
->name
, file
->fd
, prid
) < 0)
550 " report or modify preferred extent size (in bytes) for the current path\n"
552 " -R -- recursively descend (useful when current path is a directory)\n"
553 " -D -- recursively descend, only modifying extsize on directories\n"
558 get_extsize(const char *path
, int fd
)
562 if ((xfsctl(path
, fd
, XFS_IOC_FSGETXATTR
, &fsx
)) < 0) {
563 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
564 progname
, path
, strerror(errno
));
567 printf("[%u] %s\n", fsx
.fsx_extsize
, path
);
572 set_extsize(const char *path
, int fd
, long extsz
)
577 if (fstat64(fd
, &stat
) < 0) {
581 if ((xfsctl(path
, fd
, XFS_IOC_FSGETXATTR
, &fsx
)) < 0) {
582 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
583 progname
, path
, strerror(errno
));
587 if (S_ISREG(stat
.st_mode
)) {
588 fsx
.fsx_xflags
|= XFS_XFLAG_EXTSIZE
;
589 } else if (S_ISDIR(stat
.st_mode
)) {
590 fsx
.fsx_xflags
|= XFS_XFLAG_EXTSZINHERIT
;
592 printf(_("invalid target file type - file %s\n"), path
);
595 fsx
.fsx_extsize
= extsz
;
597 if ((xfsctl(path
, fd
, XFS_IOC_FSSETXATTR
, &fsx
)) < 0) {
598 printf("%s: XFS_IOC_FSSETXATTR %s: %s\n",
599 progname
, path
, strerror(errno
));
607 get_extsize_callback(
609 const struct stat
*stat
,
615 if (recurse_dir
&& !S_ISDIR(stat
->st_mode
))
618 if ((fd
= open(path
, O_RDONLY
)) == -1) {
619 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
620 progname
, path
, strerror(errno
));
622 get_extsize(path
, fd
);
629 set_extsize_callback(
631 const struct stat
*stat
,
637 if (recurse_dir
&& !S_ISDIR(stat
->st_mode
))
640 if ((fd
= open(path
, O_RDONLY
)) == -1) {
641 fprintf(stderr
, _("%s: cannot open %s: %s\n"),
642 progname
, path
, strerror(errno
));
644 set_extsize(path
, fd
, extsize
);
655 size_t blocksize
, sectsize
;
658 recurse_all
= recurse_dir
= 0;
659 init_cvtnum(&blocksize
, §size
);
660 while ((c
= getopt(argc
, argv
, "DR")) != EOF
) {
671 return command_usage(&extsize_cmd
);
676 extsize
= (long)cvtnum(blocksize
, sectsize
, argv
[optind
]);
678 printf(_("non-numeric extsize argument -- %s\n"),
686 if (recurse_all
|| recurse_dir
)
687 nftw(file
->name
, (extsize
>= 0) ?
688 set_extsize_callback
: get_extsize_callback
,
689 100, FTW_PHYS
| FTW_MOUNT
| FTW_DEPTH
);
690 else if (extsize
>= 0)
691 set_extsize(file
->name
, file
->fd
, extsize
);
693 get_extsize(file
->name
, file
->fd
);
702 struct xfs_fsop_counts fscounts
;
703 struct xfs_fsop_geom fsgeo
;
706 printf(_("fd.path = \"%s\"\n"), file
->name
);
707 if (platform_fstatfs(file
->fd
, &st
) < 0) {
710 printf(_("statfs.f_bsize = %lld\n"), (long long) st
.f_bsize
);
711 printf(_("statfs.f_blocks = %lld\n"), (long long) st
.f_blocks
);
713 printf(_("statfs.f_frsize = %lld\n"), (long long) st
.f_frsize
);
715 printf(_("statfs.f_bavail = %lld\n"), (long long) st
.f_bavail
);
717 printf(_("statfs.f_files = %lld\n"), (long long) st
.f_files
);
718 printf(_("statfs.f_ffree = %lld\n"), (long long) st
.f_ffree
);
720 if (file
->flags
& IO_FOREIGN
)
722 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSGEOMETRY_V1
, &fsgeo
)) < 0) {
723 perror("XFS_IOC_FSGEOMETRY_V1");
725 printf(_("geom.bsize = %u\n"), fsgeo
.blocksize
);
726 printf(_("geom.agcount = %u\n"), fsgeo
.agcount
);
727 printf(_("geom.agblocks = %u\n"), fsgeo
.agblocks
);
728 printf(_("geom.datablocks = %llu\n"),
729 (unsigned long long) fsgeo
.datablocks
);
730 printf(_("geom.rtblocks = %llu\n"),
731 (unsigned long long) fsgeo
.rtblocks
);
732 printf(_("geom.rtextents = %llu\n"),
733 (unsigned long long) fsgeo
.rtextents
);
734 printf(_("geom.rtextsize = %u\n"), fsgeo
.rtextsize
);
735 printf(_("geom.sunit = %u\n"), fsgeo
.sunit
);
736 printf(_("geom.swidth = %u\n"), fsgeo
.swidth
);
738 if ((xfsctl(file
->name
, file
->fd
, XFS_IOC_FSCOUNTS
, &fscounts
)) < 0) {
739 perror("XFS_IOC_FSCOUNTS");
741 printf(_("counts.freedata = %llu\n"),
742 (unsigned long long) fscounts
.freedata
);
743 printf(_("counts.freertx = %llu\n"),
744 (unsigned long long) fscounts
.freertx
);
745 printf(_("counts.freeino = %llu\n"),
746 (unsigned long long) fscounts
.freeino
);
747 printf(_("counts.allocino = %llu\n"),
748 (unsigned long long) fscounts
.allocino
);
756 open_cmd
.name
= "open";
757 open_cmd
.altname
= "o";
758 open_cmd
.cfunc
= open_f
;
760 open_cmd
.argmax
= -1;
761 open_cmd
.flags
= CMD_NOMAP_OK
| CMD_NOFILE_OK
| CMD_FOREIGN_OK
;
762 open_cmd
.args
= _("[-acdrstxT] [path]");
763 open_cmd
.oneline
= _("open the file specified by path");
764 open_cmd
.help
= open_help
;
766 stat_cmd
.name
= "stat";
767 stat_cmd
.cfunc
= stat_f
;
770 stat_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
771 stat_cmd
.args
= _("[-v]");
772 stat_cmd
.oneline
= _("statistics on the currently open file");
774 close_cmd
.name
= "close";
775 close_cmd
.altname
= "c";
776 close_cmd
.cfunc
= close_f
;
777 close_cmd
.argmin
= 0;
778 close_cmd
.argmax
= 0;
779 close_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
780 close_cmd
.oneline
= _("close the current open file");
782 statfs_cmd
.name
= "statfs";
783 statfs_cmd
.cfunc
= statfs_f
;
784 statfs_cmd
.flags
= CMD_NOMAP_OK
| CMD_FOREIGN_OK
;
786 _("statistics on the filesystem of the currently open file");
788 chproj_cmd
.name
= "chproj";
789 chproj_cmd
.cfunc
= chproj_f
;
790 chproj_cmd
.args
= _("[-D | -R] projid");
791 chproj_cmd
.argmin
= 1;
792 chproj_cmd
.argmax
= -1;
793 chproj_cmd
.flags
= CMD_NOMAP_OK
;
795 _("change project identifier on the currently open file");
796 chproj_cmd
.help
= chproj_help
;
798 lsproj_cmd
.name
= "lsproj";
799 lsproj_cmd
.cfunc
= lsproj_f
;
800 lsproj_cmd
.args
= _("[-D | -R]");
801 lsproj_cmd
.argmin
= 0;
802 lsproj_cmd
.argmax
= -1;
803 lsproj_cmd
.flags
= CMD_NOMAP_OK
;
805 _("list project identifier set on the currently open file");
806 lsproj_cmd
.help
= lsproj_help
;
808 extsize_cmd
.name
= "extsize";
809 extsize_cmd
.cfunc
= extsize_f
;
810 extsize_cmd
.args
= _("[-D | -R] [extsize]");
811 extsize_cmd
.argmin
= 0;
812 extsize_cmd
.argmax
= -1;
813 extsize_cmd
.flags
= CMD_NOMAP_OK
;
814 extsize_cmd
.oneline
=
815 _("get/set preferred extent size (in bytes) for the open file");
816 extsize_cmd
.help
= extsize_help
;
818 add_command(&open_cmd
);
819 add_command(&stat_cmd
);
820 add_command(&close_cmd
);
821 add_command(&statfs_cmd
);
822 add_command(&chproj_cmd
);
823 add_command(&lsproj_cmd
);
824 add_command(&extsize_cmd
);