]> granicus.if.org Git - strace/blob - statfs.c
bcbb73d2546bd4df19ec6d9d40359dffe166012a
[strace] / statfs.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * Copyright (c) 2003 Ulrich Drepper <drepper@redhat.com>
7  * Copyright (c) 2012 Andreas Schwab <schwab@linux-m68k.org>
8  * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "defs.h"
35 #ifdef HAVE_SYS_VFS_H
36 # include <sys/vfs.h>
37 #endif
38 #include "xlat/fsmagic.h"
39 #include "xlat/statfs_flags.h"
40
41 static const char *
42 sprintfstype(const unsigned int magic)
43 {
44         static char buf[32];
45         const char *s;
46
47         s = xlat_search(fsmagic, ARRAY_SIZE(fsmagic), magic);
48         if (s)
49                 return s;
50         sprintf(buf, "%#x", magic);
51         return buf;
52 }
53
54 static void
55 print_statfs_flags(const char *const prefix, const unsigned int flags)
56 {
57         if (flags & ST_VALID) {
58                 tprints(prefix);
59                 printflags(statfs_flags, flags, "ST_???");
60         }
61 }
62
63 static void
64 printstatfs(struct tcb *tcp, const long addr)
65 {
66         struct statfs statbuf;
67
68         if (umove_or_printaddr(tcp, addr, &statbuf))
69                 return;
70         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
71                 sprintfstype(statbuf.f_type),
72                 (unsigned long)statbuf.f_bsize,
73                 (unsigned long)statbuf.f_blocks,
74                 (unsigned long)statbuf.f_bfree);
75         tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
76                 (unsigned long)statbuf.f_bavail,
77                 (unsigned long)statbuf.f_files,
78                 (unsigned long)statbuf.f_ffree,
79                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
80         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
81 #ifdef _STATFS_F_FRSIZE
82         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
83 #endif
84 #ifdef _STATFS_F_FLAGS
85         print_statfs_flags(", f_flags=", statbuf.f_flags);
86 #endif
87         tprints("}");
88 }
89
90 SYS_FUNC(statfs)
91 {
92         if (entering(tcp)) {
93                 printpath(tcp, tcp->u_arg[0]);
94                 tprints(", ");
95         } else {
96                 printstatfs(tcp, tcp->u_arg[1]);
97         }
98         return 0;
99 }
100
101 SYS_FUNC(fstatfs)
102 {
103         if (entering(tcp)) {
104                 printfd(tcp, tcp->u_arg[0]);
105                 tprints(", ");
106         } else {
107                 printstatfs(tcp, tcp->u_arg[1]);
108         }
109         return 0;
110 }
111
112 #ifdef HAVE_STRUCT_STATFS64
113 static void
114 printstatfs64(struct tcb *tcp, long addr)
115 {
116         struct statfs64 statbuf;
117
118         if (umove_or_printaddr(tcp, addr, &statbuf))
119                 return;
120         tprintf("{f_type=%s, f_bsize=%llu, f_blocks=%llu, f_bfree=%llu, ",
121                 sprintfstype(statbuf.f_type),
122                 (unsigned long long)statbuf.f_bsize,
123                 (unsigned long long)statbuf.f_blocks,
124                 (unsigned long long)statbuf.f_bfree);
125         tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
126                 (unsigned long long)statbuf.f_bavail,
127                 (unsigned long long)statbuf.f_files,
128                 (unsigned long long)statbuf.f_ffree,
129                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
130         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
131 #ifdef _STATFS_F_FRSIZE
132         tprintf(", f_frsize=%llu", (unsigned long long)statbuf.f_frsize);
133 #endif
134 #ifdef _STATFS_F_FLAGS
135         print_statfs_flags(", f_flags=", statbuf.f_flags);
136 #endif
137         tprints("}");
138 }
139
140 struct compat_statfs64 {
141         uint32_t f_type;
142         uint32_t f_bsize;
143         uint64_t f_blocks;
144         uint64_t f_bfree;
145         uint64_t f_bavail;
146         uint64_t f_files;
147         uint64_t f_ffree;
148         fsid_t f_fsid;
149         uint32_t f_namelen;
150         uint32_t f_frsize;
151         uint32_t f_flags;
152         uint32_t f_spare[4];
153 }
154 #if defined AARCH64 || defined X86_64 || defined X32 || defined IA64
155   ATTRIBUTE_PACKED ATTRIBUTE_ALIGNED(4)
156 #endif
157 ;
158 #if defined AARCH64 || defined ARM
159 /* See arch/arm/kernel/sys_oabi-compat.c for details. */
160 # define COMPAT_STATFS64_PADDED_SIZE (sizeof(struct compat_statfs64) + 4)
161 #endif
162
163 static void
164 printcompat_statfs64(struct tcb *tcp, const long addr)
165 {
166         struct compat_statfs64 statbuf;
167
168         if (umove_or_printaddr(tcp, addr, &statbuf))
169                 return;
170         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%llu, f_bfree=%llu, ",
171                 sprintfstype(statbuf.f_type),
172                 (unsigned long)statbuf.f_bsize,
173                 (unsigned long long)statbuf.f_blocks,
174                 (unsigned long long)statbuf.f_bfree);
175         tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
176                 (unsigned long long)statbuf.f_bavail,
177                 (unsigned long long)statbuf.f_files,
178                 (unsigned long long)statbuf.f_ffree,
179                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
180         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
181         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
182         print_statfs_flags(", f_flags=", statbuf.f_flags);
183         tprints("}");
184 }
185
186 static int
187 do_statfs64_fstatfs64(struct tcb *tcp)
188 {
189         if (entering(tcp)) {
190                 tprintf(", %lu, ", tcp->u_arg[1]);
191         } else {
192                 if (tcp->u_arg[1] == sizeof(struct statfs64))
193                         printstatfs64(tcp, tcp->u_arg[2]);
194                 else if (tcp->u_arg[1] == sizeof(struct compat_statfs64)
195 #ifdef COMPAT_STATFS64_PADDED_SIZE
196                          || tcp->u_arg[1] == COMPAT_STATFS64_PADDED_SIZE
197 #endif
198                                                                         )
199                         printcompat_statfs64(tcp, tcp->u_arg[2]);
200                 else
201                         tprints("{???}");
202         }
203         return 0;
204 }
205
206 SYS_FUNC(statfs64)
207 {
208         if (entering(tcp))
209                 printpath(tcp, tcp->u_arg[0]);
210         return do_statfs64_fstatfs64(tcp);
211 }
212
213 SYS_FUNC(fstatfs64)
214 {
215         if (entering(tcp))
216                 printfd(tcp, tcp->u_arg[0]);
217         return do_statfs64_fstatfs64(tcp);
218 }
219 #endif /* HAVE_STRUCT_STATFS64 */