]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/readdir.c
xfsprogs: make static things static
[thirdparty/xfsprogs-dev.git] / io / readdir.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
3bc05641
BF
2/*
3 * Copyright (c) 2013 Red Hat, Inc.
4 * All Rights Reserved.
3bc05641
BF
5 */
6
6b803e5a
CH
7#include "command.h"
8#include "input.h"
3bc05641
BF
9#include "init.h"
10#include "io.h"
11
12#include <sys/types.h>
13#include <dirent.h>
14
2b86cff7
RS
15#ifndef _DIRENT_HAVE_D_RECLEN
16#include <string.h>
17#endif
18
3bc05641
BF
19static struct cmdinfo readdir_cmd;
20
00ff2b10 21static const char *d_type_str(unsigned int type)
3bc05641
BF
22{
23 const char *str;
24
25 switch (type) {
26 case DT_UNKNOWN:
27 str = "DT_UNKNOWN";
28 break;
29 case DT_FIFO:
30 str = "DT_FIFO";
31 break;
32 case DT_CHR:
33 str = "DT_CHR";
34 break;
35 case DT_DIR:
36 str = "DT_DIR";
37 break;
38 case DT_BLK:
39 str = "DT_BLK";
40 break;
41 case DT_REG:
42 str = "DT_REG";
43 break;
44 case DT_LNK:
45 str = "DT_LNK";
46 break;
47 case DT_SOCK:
48 str = "DT_SOCK";
49 break;
50 case DT_WHT:
51 str = "DT_WHT";
52 break;
53 default:
54 str = "ERROR!";
55 break;
56 }
57
58 return str;
59}
60
61static void
62dump_dirent(
63 long long offset,
64 struct dirent *dirent)
65{
5e303e25
ES
66 printf("%08llx: d_ino: 0x%08llx", offset,
67 (unsigned long long)dirent->d_ino);
3bc05641 68#ifdef _DIRENT_HAVE_D_OFF
5e303e25 69 printf(" d_off: 0x%08llx", (unsigned long long)dirent->d_off);
3bc05641
BF
70#endif
71#ifdef _DIRENT_HAVE_D_RECLEN
72 printf(" d_reclen: 0x%x", dirent->d_reclen);
73#endif
74#ifdef _DIRENT_HAVE_D_TYPE
75 printf(" d_type: %s", d_type_str(dirent->d_type));
76#endif
77 printf(" d_name: %s\n", dirent->d_name);
78}
79
80static int
81read_directory(
82 DIR *dir,
83 long long offset,
84 unsigned long long length,
85 int dump,
86 unsigned long long *total)
87{
88 struct dirent *dirent;
89 int count = 0;
90
91 seekdir(dir, offset);
92
93 *total = 0;
94 while (*total < length) {
95 dirent = readdir(dir);
96 if (!dirent)
97 break;
98
19863f7b 99#ifdef _DIRENT_HAVE_D_RECLEN
3bc05641 100 *total += dirent->d_reclen;
19863f7b 101#else
2b86cff7 102 *total += strlen(dirent->d_name) + sizeof(*dirent);
19863f7b 103#endif
3bc05641
BF
104 count++;
105
106 if (dump) {
107 dump_dirent(offset, dirent);
19863f7b 108#ifdef _DIRENT_HAVE_D_OFF
3bc05641 109 offset = dirent->d_off;
19863f7b
JT
110#else
111 /* Some platforms don't have dirent->d_off, but because
112 * it is used only for dumping the value, it should be
113 * safe to only set it to zero in such case.
114 */
115 offset = 0;
116#endif
3bc05641
BF
117 }
118 }
119
120 return count;
121}
122
123static int
124readdir_f(
125 int argc,
126 char **argv)
127{
128 int cnt;
129 unsigned long long total;
130 int c;
131 size_t fsblocksize, fssectsize;
132 struct timeval t1, t2;
133 char s1[64], s2[64], ts[64];
134 long long offset = -1;
135 unsigned long long length = -1; /* max length limit */
136 int verbose = 0;
137 DIR *dir;
138 int dfd;
139
140 init_cvtnum(&fsblocksize, &fssectsize);
141
142 while ((c = getopt(argc, argv, "l:o:v")) != EOF) {
143 switch (c) {
144 case 'l':
145 length = cvtnum(fsblocksize, fssectsize, optarg);
146 break;
147 case 'o':
148 offset = cvtnum(fsblocksize, fssectsize, optarg);
149 break;
150 case 'v':
151 verbose = 1;
152 break;
153 default:
154 return command_usage(&readdir_cmd);
155 }
156 }
157
158 dfd = dup(file->fd);
159 if (dfd < 0)
160 return -1;
161
162 dir = fdopendir(dfd);
163 if (!dir) {
164 close(dfd);
165 return -1;
166 }
167
168 if (offset == -1) {
169 rewinddir(dir);
170 offset = telldir(dir);
171 }
172
173 gettimeofday(&t1, NULL);
174 cnt = read_directory(dir, offset, length, verbose, &total);
175 gettimeofday(&t2, NULL);
176
177 closedir(dir);
11e06961 178 close(dfd);
3bc05641
BF
179
180 t2 = tsub(t2, t1);
181 timestr(&t2, ts, sizeof(ts), 0);
182
183 cvtstr(total, s1, sizeof(s1));
184 cvtstr(tdiv(total, t2), s2, sizeof(s2));
185
186 printf(_("read %llu bytes from offset %lld\n"), total, offset);
187 printf(_("%s, %d ops, %s (%s/sec and %.4f ops/sec)\n"),
188 s1, cnt, ts, s2, tdiv(cnt, t2));
189
190 return 0;
191}
192
193void
194readdir_init(void)
195{
196 readdir_cmd.name = "readdir";
197 readdir_cmd.cfunc = readdir_f;
198 readdir_cmd.argmax = 5;
199 readdir_cmd.flags = CMD_NOMAP_OK|CMD_FOREIGN_OK;
200 readdir_cmd.args = _("[-v][-o offset][-l length]");
201 readdir_cmd.oneline = _("read directory entries");
202
203 add_command(&readdir_cmd);
204}