blob: ad60770f8e671d0681544c449db33d7f950336d5 [file] [log] [blame]
Mike Frysingerebee04c2012-04-17 22:19:31 -04001/*
2 * Copyright (c) 2012 The Chromium OS Authors.
Elliott Hughes28e98bc2018-06-14 16:59:04 -07003 * Copyright (c) 2012-2018 The strace developers.
Mike Frysingerebee04c2012-04-17 22:19:31 -04004 * Written by Mike Frysinger <vapier@gentoo.org>.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "defs.h"
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030030#include <linux/ioctl.h>
Mike Frysingerebee04c2012-04-17 22:19:31 -040031#include <linux/loop.h>
32
Elliott Hughesd35df492017-02-15 15:19:05 -080033typedef struct loop_info struct_loop_info;
34
35#include DEF_MPERS_TYPE(struct_loop_info)
36
37#include MPERS_DEFS
38
Elliott Hughes77c3ff82017-09-08 17:11:00 -070039#include "print_fields.h"
Elliott Hughesd35df492017-02-15 15:19:05 -080040#include "xlat/loop_cmds.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000041#include "xlat/loop_flags_options.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000042#include "xlat/loop_crypt_type_options.h"
Mike Frysingerebee04c2012-04-17 22:19:31 -040043
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030044static void
Elliott Hughesd35df492017-02-15 15:19:05 -080045decode_loop_info(struct tcb *const tcp, const kernel_ulong_t addr)
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030046{
Elliott Hughesd35df492017-02-15 15:19:05 -080047 struct_loop_info info;
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030048
49 tprints(", ");
50 if (umove_or_printaddr(tcp, addr, &info))
51 return;
52
Dmitry V. Levin25129ac2016-05-29 22:28:28 +000053 tprintf("{lo_number=%d", info.lo_number);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030054
55 if (!abbrev(tcp)) {
Elliott Hughes77c3ff82017-09-08 17:11:00 -070056 PRINT_FIELD_DEV(", ", info, lo_device);
Elliott Hughesd35df492017-02-15 15:19:05 -080057 tprintf(", lo_inode=%" PRI_klu, (kernel_ulong_t) info.lo_inode);
Elliott Hughes77c3ff82017-09-08 17:11:00 -070058 PRINT_FIELD_DEV(", ", info, lo_rdevice);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030059 }
60
Dmitry V. Levin25129ac2016-05-29 22:28:28 +000061 tprintf(", lo_offset=%#x", info.lo_offset);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030062
63 if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
Dmitry V. Levin25129ac2016-05-29 22:28:28 +000064 tprints(", lo_encrypt_type=");
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030065 printxval(loop_crypt_type_options, info.lo_encrypt_type,
66 "LO_CRYPT_???");
Elliott Hughesd35df492017-02-15 15:19:05 -080067 /*
68 * It is converted to unsigned before use in kernel, see
69 * loop_info64_from_old in drivers/block/loop.c
70 */
71 tprintf(", lo_encrypt_key_size=%" PRIu32,
72 (uint32_t) info.lo_encrypt_key_size);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030073 }
74
Dmitry V. Levin25129ac2016-05-29 22:28:28 +000075 tprints(", lo_flags=");
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030076 printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???");
77
Elliott Hughes77c3ff82017-09-08 17:11:00 -070078 PRINT_FIELD_CSTRING(", ", info, lo_name);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030079
80 if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
Elliott Hughes77c3ff82017-09-08 17:11:00 -070081 const unsigned int lo_encrypt_key_size =
82 MIN((unsigned) info.lo_encrypt_key_size, LO_KEY_SIZE);
83 PRINT_FIELD_STRING(", ", info, lo_encrypt_key,
84 lo_encrypt_key_size, 0);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030085 }
86
87 if (!abbrev(tcp))
Elliott Hughesd35df492017-02-15 15:19:05 -080088 tprintf(", lo_init=[%#" PRI_klx ", %#" PRI_klx "]"
89 ", reserved=[%#hhx, %#hhx, %#hhx, %#hhx]}",
90 (kernel_ulong_t) info.lo_init[0],
91 (kernel_ulong_t) info.lo_init[1],
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +030092 info.reserved[0], info.reserved[1],
93 info.reserved[2], info.reserved[3]);
94 else
95 tprints(", ...}");
96}
97
98static void
Elliott Hughesd35df492017-02-15 15:19:05 -080099decode_loop_info64(struct tcb *const tcp, const kernel_ulong_t addr)
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300100{
101 struct loop_info64 info64;
102
103 tprints(", ");
104 if (umove_or_printaddr(tcp, addr, &info64))
105 return;
106
107 if (!abbrev(tcp)) {
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700108 PRINT_FIELD_DEV("{", info64, lo_device);
Elliott Hughesd35df492017-02-15 15:19:05 -0800109 tprintf(", lo_inode=%" PRIu64, (uint64_t) info64.lo_inode);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700110 PRINT_FIELD_DEV(", ", info64, lo_rdevice);
Elliott Hughesd35df492017-02-15 15:19:05 -0800111 tprintf(", lo_offset=%#" PRIx64 ", lo_sizelimit=%" PRIu64
112 ", lo_number=%" PRIu32,
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300113 (uint64_t) info64.lo_offset,
114 (uint64_t) info64.lo_sizelimit,
115 (uint32_t) info64.lo_number);
116 } else {
Dmitry V. Levin25129ac2016-05-29 22:28:28 +0000117 tprintf("{lo_offset=%#" PRIx64 ", lo_number=%" PRIu32,
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300118 (uint64_t) info64.lo_offset,
119 (uint32_t) info64.lo_number);
120 }
121
122 if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
Dmitry V. Levin25129ac2016-05-29 22:28:28 +0000123 tprints(", lo_encrypt_type=");
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300124 printxval(loop_crypt_type_options, info64.lo_encrypt_type,
125 "LO_CRYPT_???");
Dmitry V. Levin25129ac2016-05-29 22:28:28 +0000126 tprintf(", lo_encrypt_key_size=%" PRIu32,
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300127 info64.lo_encrypt_key_size);
128 }
129
Dmitry V. Levin25129ac2016-05-29 22:28:28 +0000130 tprints(", lo_flags=");
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300131 printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???");
132
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700133 PRINT_FIELD_CSTRING(", ", info64, lo_file_name);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300134
135 if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700136 PRINT_FIELD_CSTRING(", ", info64, lo_crypt_name);
137 const unsigned int lo_encrypt_key_size =
138 MIN((unsigned) info64.lo_encrypt_key_size, LO_KEY_SIZE);
139 PRINT_FIELD_STRING(", ", info64, lo_encrypt_key,
140 lo_encrypt_key_size, 0);
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300141 }
142
143 if (!abbrev(tcp))
Dmitry V. Levinb7166a62016-05-29 22:34:30 +0000144 tprintf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300145 (uint64_t) info64.lo_init[0],
146 (uint64_t) info64.lo_init[1]);
147 else
148 tprints(", ...}");
149}
150
Elliott Hughesd35df492017-02-15 15:19:05 -0800151MPERS_PRINTER_DECL(int, loop_ioctl,
152 struct tcb *tcp, const unsigned int code,
153 const kernel_ulong_t arg)
Mike Frysingerebee04c2012-04-17 22:19:31 -0400154{
Mike Frysingerebee04c2012-04-17 22:19:31 -0400155 switch (code) {
Mike Frysingerebee04c2012-04-17 22:19:31 -0400156 case LOOP_GET_STATUS:
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300157 if (entering(tcp))
Mike Frysingerebee04c2012-04-17 22:19:31 -0400158 return 0;
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700159 ATTRIBUTE_FALLTHROUGH;
Dmitry V. Levinbece24d2016-05-29 22:15:53 +0000160 case LOOP_SET_STATUS:
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300161 decode_loop_info(tcp, arg);
162 break;
Mike Frysingerebee04c2012-04-17 22:19:31 -0400163
Mike Frysingerebee04c2012-04-17 22:19:31 -0400164 case LOOP_GET_STATUS64:
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300165 if (entering(tcp))
Mike Frysingerebee04c2012-04-17 22:19:31 -0400166 return 0;
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700167 ATTRIBUTE_FALLTHROUGH;
Dmitry V. Levinbece24d2016-05-29 22:15:53 +0000168 case LOOP_SET_STATUS64:
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300169 decode_loop_info64(tcp, arg);
170 break;
Mike Frysingerebee04c2012-04-17 22:19:31 -0400171
172 case LOOP_CLR_FD:
173 case LOOP_SET_CAPACITY:
Mike Frysingerebee04c2012-04-17 22:19:31 -0400174 /* newer loop-control stuff */
175 case LOOP_CTL_GET_FREE:
Mike Frysingerebee04c2012-04-17 22:19:31 -0400176 /* Takes no arguments */
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300177 break;
Mike Frysingerebee04c2012-04-17 22:19:31 -0400178
179 case LOOP_SET_FD:
180 case LOOP_CHANGE_FD:
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300181 tprints(", ");
182 printfd(tcp, arg);
183 break;
184
Mike Frysingerebee04c2012-04-17 22:19:31 -0400185 /* newer loop-control stuff */
186 case LOOP_CTL_ADD:
187 case LOOP_CTL_REMOVE:
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300188 tprintf(", %d", (int) arg);
189 break;
Mike Frysingerebee04c2012-04-17 22:19:31 -0400190
Dmitry V. Levin4b9fa902016-05-29 22:58:56 +0000191 case LOOP_SET_DIRECT_IO:
Elliott Hughesbbf97dc2017-11-15 16:45:52 -0800192 case LOOP_SET_BLOCK_SIZE:
Elliott Hughesd35df492017-02-15 15:19:05 -0800193 tprintf(", %" PRI_klu, arg);
Dmitry V. Levin4b9fa902016-05-29 22:58:56 +0000194 break;
Dmitry V. Levin4b9fa902016-05-29 22:58:56 +0000195
Mike Frysingerebee04c2012-04-17 22:19:31 -0400196 default:
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300197 return RVAL_DECODED;
Mike Frysingerebee04c2012-04-17 22:19:31 -0400198 }
Dmitry V. Levin3cfabeb2015-07-04 17:40:02 +0300199
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700200 return RVAL_IOCTL_DECODED;
Mike Frysingerebee04c2012-04-17 22:19:31 -0400201}