]> granicus.if.org Git - strace/blob - statfs.c
swapon.c: make use of RVAL_DECODED
[strace] / statfs.c
1 #include "defs.h"
2 #ifdef HAVE_SYS_VFS_H
3 # include <sys/vfs.h>
4 #endif
5 #include "xlat/fsmagic.h"
6
7 static const char *
8 sprintfstype(const unsigned int magic)
9 {
10         static char buf[32];
11         const char *s;
12
13         s = xlat_search(fsmagic, ARRAY_SIZE(fsmagic), magic);
14         if (s) {
15                 sprintf(buf, "\"%s\"", s);
16                 return buf;
17         }
18         sprintf(buf, "%#x", magic);
19         return buf;
20 }
21
22 static void
23 printstatfs(struct tcb *tcp, const long addr)
24 {
25         struct statfs statbuf;
26
27         if (syserror(tcp) || !verbose(tcp)) {
28                 tprintf("%#lx", addr);
29                 return;
30         }
31         if (umove(tcp, addr, &statbuf) < 0) {
32                 tprints("{...}");
33                 return;
34         }
35         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
36                 sprintfstype(statbuf.f_type),
37                 (unsigned long)statbuf.f_bsize,
38                 (unsigned long)statbuf.f_blocks,
39                 (unsigned long)statbuf.f_bfree);
40         tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
41                 (unsigned long)statbuf.f_bavail,
42                 (unsigned long)statbuf.f_files,
43                 (unsigned long)statbuf.f_ffree,
44                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
45         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
46 #ifdef _STATFS_F_FRSIZE
47         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
48 #endif
49 #ifdef _STATFS_F_FLAGS
50         tprintf(", f_flags=%lu", (unsigned long)statbuf.f_flags);
51 #endif
52         tprints("}");
53 }
54
55 SYS_FUNC(statfs)
56 {
57         if (entering(tcp)) {
58                 printpath(tcp, tcp->u_arg[0]);
59                 tprints(", ");
60         } else {
61                 printstatfs(tcp, tcp->u_arg[1]);
62         }
63         return 0;
64 }
65
66 SYS_FUNC(fstatfs)
67 {
68         if (entering(tcp)) {
69                 printfd(tcp, tcp->u_arg[0]);
70                 tprints(", ");
71         } else {
72                 printstatfs(tcp, tcp->u_arg[1]);
73         }
74         return 0;
75 }
76
77 #ifdef HAVE_STRUCT_STATFS64
78 static void
79 printstatfs64(struct tcb *tcp, long addr)
80 {
81         struct statfs64 statbuf;
82
83         if (syserror(tcp) || !verbose(tcp)) {
84                 tprintf("%#lx", addr);
85                 return;
86         }
87         if (umove(tcp, addr, &statbuf) < 0) {
88                 tprints("{...}");
89                 return;
90         }
91         tprintf("{f_type=%s, f_bsize=%llu, f_blocks=%llu, f_bfree=%llu, ",
92                 sprintfstype(statbuf.f_type),
93                 (unsigned long long)statbuf.f_bsize,
94                 (unsigned long long)statbuf.f_blocks,
95                 (unsigned long long)statbuf.f_bfree);
96         tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
97                 (unsigned long long)statbuf.f_bavail,
98                 (unsigned long long)statbuf.f_files,
99                 (unsigned long long)statbuf.f_ffree,
100                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
101         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
102 #ifdef _STATFS_F_FRSIZE
103         tprintf(", f_frsize=%llu", (unsigned long long)statbuf.f_frsize);
104 #endif
105 #ifdef _STATFS_F_FLAGS
106         tprintf(", f_flags=%llu", (unsigned long long)statbuf.f_flags);
107 #endif
108         tprints("}");
109 }
110
111 struct compat_statfs64 {
112         uint32_t f_type;
113         uint32_t f_bsize;
114         uint64_t f_blocks;
115         uint64_t f_bfree;
116         uint64_t f_bavail;
117         uint64_t f_files;
118         uint64_t f_ffree;
119         fsid_t f_fsid;
120         uint32_t f_namelen;
121         uint32_t f_frsize;
122         uint32_t f_flags;
123         uint32_t f_spare[4];
124 }
125 #if defined AARCH64 || defined X86_64 || defined X32 || defined IA64
126   ATTRIBUTE_PACKED ATTRIBUTE_ALIGNED(4)
127 #endif
128 ;
129 #if defined AARCH64 || defined ARM
130 /* See arch/arm/kernel/sys_oabi-compat.c for details. */
131 # define COMPAT_STATFS64_PADDED_SIZE (sizeof(struct compat_statfs64) + 4)
132 #endif
133
134 static void
135 printcompat_statfs64(struct tcb *tcp, const long addr)
136 {
137         struct compat_statfs64 statbuf;
138
139         if (syserror(tcp) || !verbose(tcp)) {
140                 tprintf("%#lx", addr);
141                 return;
142         }
143         if (umove(tcp, addr, &statbuf) < 0) {
144                 tprints("{...}");
145                 return;
146         }
147         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%llu, f_bfree=%llu, ",
148                 sprintfstype(statbuf.f_type),
149                 (unsigned long)statbuf.f_bsize,
150                 (unsigned long long)statbuf.f_blocks,
151                 (unsigned long long)statbuf.f_bfree);
152         tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
153                 (unsigned long long)statbuf.f_bavail,
154                 (unsigned long long)statbuf.f_files,
155                 (unsigned long long)statbuf.f_ffree,
156                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
157         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
158         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
159         tprintf(", f_flags=%lu}", (unsigned long)statbuf.f_frsize);
160 }
161
162 static int
163 do_statfs64_fstatfs64(struct tcb *tcp)
164 {
165         if (entering(tcp)) {
166                 tprintf(", %lu, ", tcp->u_arg[1]);
167         } else {
168                 if (tcp->u_arg[1] == sizeof(struct statfs64))
169                         printstatfs64(tcp, tcp->u_arg[2]);
170                 else if (tcp->u_arg[1] == sizeof(struct compat_statfs64)
171 #ifdef COMPAT_STATFS64_PADDED_SIZE
172                          || tcp->u_arg[1] == COMPAT_STATFS64_PADDED_SIZE
173 #endif
174                                                                         )
175                         printcompat_statfs64(tcp, tcp->u_arg[2]);
176                 else
177                         tprints("{???}");
178         }
179         return 0;
180 }
181
182 SYS_FUNC(statfs64)
183 {
184         if (entering(tcp))
185                 printpath(tcp, tcp->u_arg[0]);
186         return do_statfs64_fstatfs64(tcp);
187 }
188
189 SYS_FUNC(fstatfs64)
190 {
191         if (entering(tcp))
192                 printfd(tcp, tcp->u_arg[0]);
193         return do_statfs64_fstatfs64(tcp);
194 }
195 #endif /* HAVE_STRUCT_STATFS64 */
196
197 #ifdef ALPHA
198 SYS_FUNC(osf_statfs)
199 {
200         if (entering(tcp)) {
201                 printpath(tcp, tcp->u_arg[0]);
202                 tprints(", ");
203         } else {
204                 printstatfs(tcp, tcp->u_arg[1]);
205                 tprintf(", %lu", tcp->u_arg[2]);
206         }
207         return 0;
208 }
209
210 SYS_FUNC(osf_fstatfs)
211 {
212         if (entering(tcp)) {
213                 tprintf("%lu, ", tcp->u_arg[0]);
214         } else {
215                 printstatfs(tcp, tcp->u_arg[1]);
216                 tprintf(", %lu", tcp->u_arg[2]);
217         }
218         return 0;
219 }
220 #endif /* ALPHA */