2 * Copyright (c) 2012 The Chromium OS Authors.
3 * Copyright (c) 2012-2018 The strace developers.
4 * Written by Mike Frysinger <vapier@gentoo.org>.
6 * SPDX-License-Identifier: LGPL-2.1-or-later
10 #include <linux/ioctl.h>
11 #include <linux/loop.h>
13 typedef struct loop_info struct_loop_info;
15 #include DEF_MPERS_TYPE(struct_loop_info)
19 #include "print_fields.h"
21 #define XLAT_MACROS_ONLY
22 #include "xlat/loop_cmds.h"
23 #undef XLAT_MACROS_ONLY
25 #include "xlat/loop_flags_options.h"
26 #include "xlat/loop_crypt_type_options.h"
29 decode_loop_info(struct tcb *const tcp, const kernel_ulong_t addr)
31 struct_loop_info info;
34 if (umove_or_printaddr(tcp, addr, &info))
37 tprintf("{lo_number=%d", info.lo_number);
40 PRINT_FIELD_DEV(", ", info, lo_device);
41 tprintf(", lo_inode=%" PRI_klu, (kernel_ulong_t) info.lo_inode);
42 PRINT_FIELD_DEV(", ", info, lo_rdevice);
45 tprintf(", lo_offset=%#x", info.lo_offset);
47 if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
48 tprints(", lo_encrypt_type=");
49 printxval(loop_crypt_type_options, info.lo_encrypt_type,
52 * It is converted to unsigned before use in kernel, see
53 * loop_info64_from_old in drivers/block/loop.c
55 tprintf(", lo_encrypt_key_size=%" PRIu32,
56 (uint32_t) info.lo_encrypt_key_size);
59 tprints(", lo_flags=");
60 printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???");
62 PRINT_FIELD_CSTRING(", ", info, lo_name);
64 if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
65 const unsigned int lo_encrypt_key_size =
66 MIN((unsigned) info.lo_encrypt_key_size, LO_KEY_SIZE);
67 PRINT_FIELD_STRING(", ", info, lo_encrypt_key,
68 lo_encrypt_key_size, 0);
72 tprintf(", lo_init=[%#" PRI_klx ", %#" PRI_klx "]"
73 ", reserved=[%#hhx, %#hhx, %#hhx, %#hhx]}",
74 (kernel_ulong_t) info.lo_init[0],
75 (kernel_ulong_t) info.lo_init[1],
76 info.reserved[0], info.reserved[1],
77 info.reserved[2], info.reserved[3]);
83 decode_loop_info64(struct tcb *const tcp, const kernel_ulong_t addr)
85 struct loop_info64 info64;
88 if (umove_or_printaddr(tcp, addr, &info64))
92 PRINT_FIELD_DEV("{", info64, lo_device);
93 tprintf(", lo_inode=%" PRIu64, (uint64_t) info64.lo_inode);
94 PRINT_FIELD_DEV(", ", info64, lo_rdevice);
95 tprintf(", lo_offset=%#" PRIx64 ", lo_sizelimit=%" PRIu64
96 ", lo_number=%" PRIu32,
97 (uint64_t) info64.lo_offset,
98 (uint64_t) info64.lo_sizelimit,
99 (uint32_t) info64.lo_number);
101 tprintf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32,
102 (uint64_t) info64.lo_offset,
103 (uint32_t) info64.lo_number);
106 if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
107 tprints(", lo_encrypt_type=");
108 printxval(loop_crypt_type_options, info64.lo_encrypt_type,
110 tprintf(", lo_encrypt_key_size=%" PRIu32,
111 info64.lo_encrypt_key_size);
114 tprints(", lo_flags=");
115 printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???");
117 PRINT_FIELD_CSTRING(", ", info64, lo_file_name);
119 if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
120 PRINT_FIELD_CSTRING(", ", info64, lo_crypt_name);
121 const unsigned int lo_encrypt_key_size =
122 MIN((unsigned) info64.lo_encrypt_key_size, LO_KEY_SIZE);
123 PRINT_FIELD_STRING(", ", info64, lo_encrypt_key,
124 lo_encrypt_key_size, 0);
128 tprintf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
129 (uint64_t) info64.lo_init[0],
130 (uint64_t) info64.lo_init[1]);
135 MPERS_PRINTER_DECL(int, loop_ioctl,
136 struct tcb *tcp, const unsigned int code,
137 const kernel_ulong_t arg)
140 case LOOP_GET_STATUS:
143 ATTRIBUTE_FALLTHROUGH;
144 case LOOP_SET_STATUS:
145 decode_loop_info(tcp, arg);
148 case LOOP_GET_STATUS64:
151 ATTRIBUTE_FALLTHROUGH;
152 case LOOP_SET_STATUS64:
153 decode_loop_info64(tcp, arg);
157 case LOOP_SET_CAPACITY:
158 /* newer loop-control stuff */
159 case LOOP_CTL_GET_FREE:
160 /* Takes no arguments */
169 /* newer loop-control stuff */
171 case LOOP_CTL_REMOVE:
172 tprintf(", %d", (int) arg);
175 case LOOP_SET_DIRECT_IO:
176 case LOOP_SET_BLOCK_SIZE:
177 tprintf(", %" PRI_klu, arg);
184 return RVAL_IOCTL_DECODED;