blob: ac33c38f0273f7e59300e08f4565030757165cce [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>
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +00004 * All rights reserved.
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. Levin37d1b3d2016-05-26 10:43:51 +000030
31#include DEF_MPERS_TYPE(struct_blk_user_trace_setup)
32#include DEF_MPERS_TYPE(struct_blkpg_ioctl_arg)
33#include DEF_MPERS_TYPE(struct_blkpg_partition)
34
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000035#include <linux/blkpg.h>
36#include <linux/fs.h>
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000037
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000038#define BLKTRACE_BDEV_SIZE 32
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000039typedef struct blk_user_trace_setup {
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000040 char name[BLKTRACE_BDEV_SIZE]; /* output */
41 uint16_t act_mask; /* input */
42 uint32_t buf_size; /* input */
43 uint32_t buf_nr; /* input */
44 uint64_t start_lba;
45 uint64_t end_lba;
46 uint32_t pid;
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000047} struct_blk_user_trace_setup;
48
49typedef struct blkpg_ioctl_arg struct_blkpg_ioctl_arg;
50typedef struct blkpg_partition struct_blkpg_partition;
51
52#include MPERS_DEFS
53
54/*
55 * ioctl numbers <= 114 are present in Linux 2.4. The following ones have been
56 * added since then and headers containing them may not be available on every
57 * system.
58 */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000059
60#ifndef BLKTRACESETUP
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +000061# define BLKTRACESETUP _IOWR(0x12, 115, struct_blk_user_trace_setup)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000062#endif
63#ifndef BLKTRACESTART
Dmitry V. Levina0beac12015-07-05 15:15:03 +030064# define BLKTRACESTART _IO(0x12,116)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000065#endif
Dmitry V. Levin4cee0af2011-04-07 19:58:10 +000066#ifndef BLKTRACESTOP
Dmitry V. Levina0beac12015-07-05 15:15:03 +030067# define BLKTRACESTOP _IO(0x12,117)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000068#endif
69#ifndef BLKTRACETEARDOWN
Dmitry V. Levina0beac12015-07-05 15:15:03 +030070# define BLKTRACETEARDOWN _IO(0x12,118)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000071#endif
72#ifndef BLKDISCARD
Dmitry V. Levina0beac12015-07-05 15:15:03 +030073# define BLKDISCARD _IO(0x12,119)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000074#endif
75#ifndef BLKIOMIN
Dmitry V. Levina0beac12015-07-05 15:15:03 +030076# define BLKIOMIN _IO(0x12,120)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000077#endif
78#ifndef BLKIOOPT
Dmitry V. Levina0beac12015-07-05 15:15:03 +030079# define BLKIOOPT _IO(0x12,121)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000080#endif
81#ifndef BLKALIGNOFF
Dmitry V. Levina0beac12015-07-05 15:15:03 +030082# define BLKALIGNOFF _IO(0x12,122)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000083#endif
84#ifndef BLKPBSZGET
Dmitry V. Levina0beac12015-07-05 15:15:03 +030085# define BLKPBSZGET _IO(0x12,123)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000086#endif
87#ifndef BLKDISCARDZEROES
Dmitry V. Levina0beac12015-07-05 15:15:03 +030088# define BLKDISCARDZEROES _IO(0x12,124)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000089#endif
90#ifndef BLKSECDISCARD
Dmitry V. Levina0beac12015-07-05 15:15:03 +030091# define BLKSECDISCARD _IO(0x12,125)
92#endif
93#ifndef BLKROTATIONAL
94# define BLKROTATIONAL _IO(0x12,126)
95#endif
96#ifndef BLKZEROOUT
97# define BLKZEROOUT _IO(0x12,127)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000098#endif
Dmitry V. Levina41fdb52016-05-25 07:33:02 +000099#ifndef BLKDAXGET
100# define BLKDAXGET _IO(0x12,129)
101#endif
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000102
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000103#include "xlat/blkpg_ops.h"
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000104
105static void
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000106print_blkpg_req(struct tcb *tcp, const struct_blkpg_ioctl_arg *blkpg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000107{
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000108 struct_blkpg_partition p;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000109
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200110 tprints("{");
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000111 printxval(blkpg_ops, blkpg->op, "BLKPG_???");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000112
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300113 tprintf(", flags=%d, datalen=%d, data=",
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000114 blkpg->flags, blkpg->datalen);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000115
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300116 if (!umove_or_printaddr(tcp, (long) blkpg->data, &p)) {
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000117 tprintf("{start=%lld, length=%lld, pno=%d, devname=",
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000118 (long long) p.start, (long long) p.length, p.pno);
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000119 print_quoted_string(p.devname, sizeof(p.devname),
120 QUOTE_0_TERMINATED);
121 tprints(", volname=");
122 print_quoted_string(p.volname, sizeof(p.volname),
123 QUOTE_0_TERMINATED);
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300124 tprints("}");
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000125 }
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300126 tprints("}");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000127}
128
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000129MPERS_PRINTER_DECL(int, block_ioctl, struct tcb *tcp,
130 const unsigned int code, const long arg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000131{
132 switch (code) {
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000133 /* take arg as a value, not as a pointer */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000134 case BLKRASET:
135 case BLKFRASET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300136 tprintf(", %lu", arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000137 break;
138
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300139 /* return an unsigned short */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000140 case BLKSECTGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300141 case BLKROTATIONAL:
142 if (entering(tcp))
143 return 0;
144 tprints(", ");
145 printnum_short(tcp, arg, "%hu");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000146 break;
147
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000148 /* return a signed int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000149 case BLKROGET:
150 case BLKBSZGET:
151 case BLKSSZGET:
152 case BLKALIGNOFF:
Dmitry V. Levina41fdb52016-05-25 07:33:02 +0000153 case BLKDAXGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300154 if (entering(tcp))
155 return 0;
Dmitry V. Levin0c9087c2016-05-26 12:36:56 +0000156 /* fall through */
157 /* take a signed int */
158 case BLKROSET:
159 case BLKBSZSET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300160 tprints(", ");
161 printnum_int(tcp, arg, "%d");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000162 break;
163
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000164 /* return an unsigned int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000165 case BLKPBSZGET:
166 case BLKIOMIN:
167 case BLKIOOPT:
168 case BLKDISCARDZEROES:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300169 if (entering(tcp))
170 return 0;
171 tprints(", ");
172 printnum_int(tcp, arg, "%u");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000173 break;
174
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000175 /* return a signed long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000176 case BLKRAGET:
177 case BLKFRAGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300178 if (entering(tcp))
179 return 0;
180 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000181 printnum_slong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000182 break;
183
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000184 /* returns an unsigned long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000185 case BLKGETSIZE:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300186 if (entering(tcp))
187 return 0;
188 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000189 printnum_ulong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000190 break;
191
Dmitry V. Levin25caa312011-08-16 21:36:16 +0000192#ifdef HAVE_BLKGETSIZE64
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300193 /* returns an uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000194 case BLKGETSIZE64:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300195 if (entering(tcp))
196 return 0;
197 tprints(", ");
198 printnum_int64(tcp, arg, "%" PRIu64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000199 break;
Denys Vlasenko5bd67c82011-08-15 11:36:09 +0200200#endif
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000201
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300202 /* takes a pair of uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000203 case BLKDISCARD:
204 case BLKSECDISCARD:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300205 case BLKZEROOUT:
206 tprints(", ");
Dmitry V. Levin46d25c22016-05-26 12:33:21 +0000207 printpair_int64(tcp, arg, "%" PRIu64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000208 break;
209
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300210 /* More complex types */
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300211 case BLKPG: {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000212 struct_blkpg_ioctl_arg blkpg;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300213
214 tprints(", ");
215 if (!umove_or_printaddr(tcp, arg, &blkpg))
216 print_blkpg_req(tcp, &blkpg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000217 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300218 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000219
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000220 case BLKTRACESETUP:
221 if (entering(tcp)) {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000222 struct_blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300223
224 tprints(", ");
225 if (umove_or_printaddr(tcp, arg, &buts))
226 break;
227 tprintf("{act_mask=%u, buf_size=%u, "
228 "buf_nr=%u, start_lba=%" PRIu64 ", "
229 "end_lba=%" PRIu64 ", pid=%u",
230 (unsigned)buts.act_mask, buts.buf_size,
231 buts.buf_nr, buts.start_lba,
232 buts.end_lba, buts.pid);
233 return 1;
234 } else {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000235 struct_blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300236
Dmitry V. Levin0bea5282016-05-26 10:04:39 +0000237 if (!syserror(tcp) && !umove(tcp, arg, &buts)) {
238 tprints(", name=");
239 print_quoted_string(buts.name, sizeof(buts.name),
240 QUOTE_0_TERMINATED);
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000241 }
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300242 tprints("}");
243 break;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000244 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000245
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300246 /* No arguments */
247 case BLKRRPART:
248 case BLKFLSBUF:
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000249 case BLKTRACESTART:
250 case BLKTRACESTOP:
251 case BLKTRACETEARDOWN:
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000252 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300253 default:
254 return RVAL_DECODED;
255 }
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000256
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300257 return RVAL_DECODED | 1;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000258}