Home | History | Annotate | Download | only in strace
      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 */
    221