blob: 5edb9b6f569f667410001485aaac7ff56a2cf471 [file] [log] [blame]
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +00001/*
2 * Copyright (c) 2009, 2010 Jeff Mahoney <jeffm@suse.com>
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +00003 * Copyright (c) 2011-2016 Dmitry V. Levin <ldv@altlinux.org>
Elliott Hughes28e98bc2018-06-14 16:59:04 -07004 * Copyright (c) 2011-2018 The strace developers.
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +00005 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "defs.h"
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000031
32#include DEF_MPERS_TYPE(struct_blk_user_trace_setup)
33#include DEF_MPERS_TYPE(struct_blkpg_ioctl_arg)
34#include DEF_MPERS_TYPE(struct_blkpg_partition)
35
Elliott Hughesd35df492017-02-15 15:19:05 -080036#include <linux/ioctl.h>
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000037#include <linux/fs.h>
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000038
Elliott Hughesd35df492017-02-15 15:19:05 -080039typedef struct {
40 int op;
41 int flags;
42 int datalen;
43 void *data;
44} struct_blkpg_ioctl_arg;
45
46#define BLKPG_DEVNAMELTH 64
47#define BLKPG_VOLNAMELTH 64
48typedef struct {
49 int64_t start; /* starting offset in bytes */
50 int64_t length; /* length in bytes */
51 int pno; /* partition number */
52 char devname[BLKPG_DEVNAMELTH]; /* partition name, like sda5 or c0d1p2,
53 to be used in kernel messages */
54 char volname[BLKPG_VOLNAMELTH]; /* volume label */
55} struct_blkpg_partition;
56
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000057#define BLKTRACE_BDEV_SIZE 32
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000058typedef struct blk_user_trace_setup {
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000059 char name[BLKTRACE_BDEV_SIZE]; /* output */
60 uint16_t act_mask; /* input */
61 uint32_t buf_size; /* input */
62 uint32_t buf_nr; /* input */
63 uint64_t start_lba;
64 uint64_t end_lba;
65 uint32_t pid;
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000066} struct_blk_user_trace_setup;
67
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000068#include MPERS_DEFS
69
Elliott Hughes77c3ff82017-09-08 17:11:00 -070070#include "print_fields.h"
71
Elliott Hughesd35df492017-02-15 15:19:05 -080072#ifndef BLKPG
Elliott Hughesdc75b012017-07-05 13:54:44 -070073# define BLKPG _IO(0x12, 105)
Elliott Hughesd35df492017-02-15 15:19:05 -080074#endif
75
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000076/*
77 * ioctl numbers <= 114 are present in Linux 2.4. The following ones have been
78 * added since then and headers containing them may not be available on every
79 * system.
80 */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000081
82#ifndef BLKTRACESETUP
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000083# define BLKTRACESETUP _IOWR(0x12, 115, struct_blk_user_trace_setup)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000084#endif
85#ifndef BLKTRACESTART
Elliott Hughesdc75b012017-07-05 13:54:44 -070086# define BLKTRACESTART _IO(0x12, 116)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000087#endif
Dmitry V. Levin4cee0af2011-04-07 19:58:10 +000088#ifndef BLKTRACESTOP
Elliott Hughesdc75b012017-07-05 13:54:44 -070089# define BLKTRACESTOP _IO(0x12, 117)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000090#endif
91#ifndef BLKTRACETEARDOWN
Elliott Hughesdc75b012017-07-05 13:54:44 -070092# define BLKTRACETEARDOWN _IO(0x12, 118)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000093#endif
94#ifndef BLKDISCARD
Elliott Hughesdc75b012017-07-05 13:54:44 -070095# define BLKDISCARD _IO(0x12, 119)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000096#endif
97#ifndef BLKIOMIN
Elliott Hughesdc75b012017-07-05 13:54:44 -070098# define BLKIOMIN _IO(0x12, 120)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000099#endif
100#ifndef BLKIOOPT
Elliott Hughesdc75b012017-07-05 13:54:44 -0700101# define BLKIOOPT _IO(0x12, 121)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000102#endif
103#ifndef BLKALIGNOFF
Elliott Hughesdc75b012017-07-05 13:54:44 -0700104# define BLKALIGNOFF _IO(0x12, 122)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000105#endif
106#ifndef BLKPBSZGET
Elliott Hughesdc75b012017-07-05 13:54:44 -0700107# define BLKPBSZGET _IO(0x12, 123)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000108#endif
109#ifndef BLKDISCARDZEROES
Elliott Hughesdc75b012017-07-05 13:54:44 -0700110# define BLKDISCARDZEROES _IO(0x12, 124)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000111#endif
112#ifndef BLKSECDISCARD
Elliott Hughesdc75b012017-07-05 13:54:44 -0700113# define BLKSECDISCARD _IO(0x12, 125)
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300114#endif
115#ifndef BLKROTATIONAL
Elliott Hughesdc75b012017-07-05 13:54:44 -0700116# define BLKROTATIONAL _IO(0x12, 126)
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300117#endif
118#ifndef BLKZEROOUT
Elliott Hughesdc75b012017-07-05 13:54:44 -0700119# define BLKZEROOUT _IO(0x12, 127)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000120#endif
121
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000122#include "xlat/blkpg_ops.h"
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000123
124static void
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000125print_blkpg_req(struct tcb *tcp, const struct_blkpg_ioctl_arg *blkpg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000126{
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000127 struct_blkpg_partition p;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000128
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700129 PRINT_FIELD_XVAL("{", *blkpg, op, blkpg_ops, "BLKPG_???");
130 PRINT_FIELD_D(", ", *blkpg, flags);
131 PRINT_FIELD_D(", ", *blkpg, datalen);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000132
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700133 tprints(", data=");
Elliott Hughesd35df492017-02-15 15:19:05 -0800134 if (!umove_or_printaddr(tcp, ptr_to_kulong(blkpg->data), &p)) {
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700135 PRINT_FIELD_D("{", p, start);
136 PRINT_FIELD_D(", ", p, length);
137 PRINT_FIELD_D(", ", p, pno);
138 PRINT_FIELD_CSTRING(", ", p, devname);
139 PRINT_FIELD_CSTRING(", ", p, volname);
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300140 tprints("}");
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000141 }
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300142 tprints("}");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000143}
144
Elliott Hughesd35df492017-02-15 15:19:05 -0800145MPERS_PRINTER_DECL(int, block_ioctl, struct tcb *const tcp,
146 const unsigned int code, const kernel_ulong_t arg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000147{
148 switch (code) {
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000149 /* take arg as a value, not as a pointer */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000150 case BLKRASET:
151 case BLKFRASET:
Elliott Hughesd35df492017-02-15 15:19:05 -0800152 tprintf(", %" PRI_klu, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000153 break;
154
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300155 /* return an unsigned short */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000156 case BLKSECTGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300157 case BLKROTATIONAL:
158 if (entering(tcp))
159 return 0;
160 tprints(", ");
161 printnum_short(tcp, arg, "%hu");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000162 break;
163
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000164 /* return a signed int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000165 case BLKROGET:
166 case BLKBSZGET:
167 case BLKSSZGET:
168 case BLKALIGNOFF:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300169 if (entering(tcp))
170 return 0;
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700171 ATTRIBUTE_FALLTHROUGH;
Dmitry V. Levin0c9087c2016-05-26 12:36:56 +0000172 /* take a signed int */
173 case BLKROSET:
174 case BLKBSZSET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300175 tprints(", ");
176 printnum_int(tcp, arg, "%d");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000177 break;
178
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000179 /* return an unsigned int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000180 case BLKPBSZGET:
181 case BLKIOMIN:
182 case BLKIOOPT:
183 case BLKDISCARDZEROES:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300184 if (entering(tcp))
185 return 0;
186 tprints(", ");
187 printnum_int(tcp, arg, "%u");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000188 break;
189
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000190 /* return a signed long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000191 case BLKRAGET:
192 case BLKFRAGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300193 if (entering(tcp))
194 return 0;
195 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000196 printnum_slong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000197 break;
198
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000199 /* returns an unsigned long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000200 case BLKGETSIZE:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300201 if (entering(tcp))
202 return 0;
203 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000204 printnum_ulong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000205 break;
206
Dmitry V. Levin25caa312011-08-16 21:36:16 +0000207#ifdef HAVE_BLKGETSIZE64
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300208 /* returns an uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000209 case BLKGETSIZE64:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300210 if (entering(tcp))
211 return 0;
212 tprints(", ");
213 printnum_int64(tcp, arg, "%" PRIu64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000214 break;
Denys Vlasenko5bd67c82011-08-15 11:36:09 +0200215#endif
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000216
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300217 /* takes a pair of uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000218 case BLKDISCARD:
219 case BLKSECDISCARD:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300220 case BLKZEROOUT:
221 tprints(", ");
Dmitry V. Levin46d25c22016-05-26 12:33:21 +0000222 printpair_int64(tcp, arg, "%" PRIu64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000223 break;
224
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300225 /* More complex types */
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300226 case BLKPG: {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000227 struct_blkpg_ioctl_arg blkpg;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300228
229 tprints(", ");
230 if (!umove_or_printaddr(tcp, arg, &blkpg))
231 print_blkpg_req(tcp, &blkpg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000232 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300233 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000234
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000235 case BLKTRACESETUP:
236 if (entering(tcp)) {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000237 struct_blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300238
239 tprints(", ");
240 if (umove_or_printaddr(tcp, arg, &buts))
241 break;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700242 PRINT_FIELD_U("{", buts, act_mask);
243 PRINT_FIELD_U(", ", buts, buf_size);
244 PRINT_FIELD_U(", ", buts, buf_nr);
245 PRINT_FIELD_U(", ", buts, start_lba);
246 PRINT_FIELD_U(", ", buts, end_lba);
247 PRINT_FIELD_U(", ", buts, pid);
248 return 0;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300249 } else {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000250 struct_blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300251
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700252 if (!syserror(tcp) && !umove(tcp, arg, &buts))
253 PRINT_FIELD_CSTRING(", ", buts, name);
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300254 tprints("}");
255 break;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000256 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000257
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300258 /* No arguments */
259 case BLKRRPART:
260 case BLKFLSBUF:
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000261 case BLKTRACESTART:
262 case BLKTRACESTOP:
263 case BLKTRACETEARDOWN:
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000264 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300265 default:
266 return RVAL_DECODED;
267 }
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000268
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700269 return RVAL_IOCTL_DECODED;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000270}