blob: 3c007464e0ac984c5d6edbe0984e931ff61e731e [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
99
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000100#include "xlat/blkpg_ops.h"
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000101
102static void
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000103print_blkpg_req(struct tcb *tcp, const struct_blkpg_ioctl_arg *blkpg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000104{
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000105 struct_blkpg_partition p;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000106
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200107 tprints("{");
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000108 printxval(blkpg_ops, blkpg->op, "BLKPG_???");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000109
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300110 tprintf(", flags=%d, datalen=%d, data=",
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000111 blkpg->flags, blkpg->datalen);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000112
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300113 if (!umove_or_printaddr(tcp, (long) blkpg->data, &p)) {
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000114 tprintf("{start=%lld, length=%lld, pno=%d, devname=",
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000115 (long long) p.start, (long long) p.length, p.pno);
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000116 print_quoted_string(p.devname, sizeof(p.devname),
117 QUOTE_0_TERMINATED);
118 tprints(", volname=");
119 print_quoted_string(p.volname, sizeof(p.volname),
120 QUOTE_0_TERMINATED);
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300121 tprints("}");
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000122 }
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300123 tprints("}");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000124}
125
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000126MPERS_PRINTER_DECL(int, block_ioctl, struct tcb *tcp,
127 const unsigned int code, const long arg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000128{
129 switch (code) {
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000130 /* take arg as a value, not as a pointer */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000131 case BLKRASET:
132 case BLKFRASET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300133 tprintf(", %lu", arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000134 break;
135
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300136 /* return an unsigned short */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000137 case BLKSECTGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300138 case BLKROTATIONAL:
139 if (entering(tcp))
140 return 0;
141 tprints(", ");
142 printnum_short(tcp, arg, "%hu");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000143 break;
144
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000145 /* return a signed int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000146 case BLKROGET:
147 case BLKBSZGET:
148 case BLKSSZGET:
149 case BLKALIGNOFF:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300150 if (entering(tcp))
151 return 0;
Dmitry V. Levin0c9087c2016-05-26 12:36:56 +0000152 /* fall through */
153 /* take a signed int */
154 case BLKROSET:
155 case BLKBSZSET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300156 tprints(", ");
157 printnum_int(tcp, arg, "%d");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000158 break;
159
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000160 /* return an unsigned int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000161 case BLKPBSZGET:
162 case BLKIOMIN:
163 case BLKIOOPT:
164 case BLKDISCARDZEROES:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300165 if (entering(tcp))
166 return 0;
167 tprints(", ");
168 printnum_int(tcp, arg, "%u");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000169 break;
170
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000171 /* return a signed long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000172 case BLKRAGET:
173 case BLKFRAGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300174 if (entering(tcp))
175 return 0;
176 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000177 printnum_slong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000178 break;
179
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000180 /* returns an unsigned long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000181 case BLKGETSIZE:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300182 if (entering(tcp))
183 return 0;
184 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000185 printnum_ulong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000186 break;
187
Dmitry V. Levin25caa312011-08-16 21:36:16 +0000188#ifdef HAVE_BLKGETSIZE64
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300189 /* returns an uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000190 case BLKGETSIZE64:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300191 if (entering(tcp))
192 return 0;
193 tprints(", ");
194 printnum_int64(tcp, arg, "%" PRIu64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000195 break;
Denys Vlasenko5bd67c82011-08-15 11:36:09 +0200196#endif
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000197
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300198 /* takes a pair of uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000199 case BLKDISCARD:
200 case BLKSECDISCARD:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300201 case BLKZEROOUT:
202 tprints(", ");
Dmitry V. Levin46d25c22016-05-26 12:33:21 +0000203 printpair_int64(tcp, arg, "%" PRIu64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000204 break;
205
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300206 /* More complex types */
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300207 case BLKPG: {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000208 struct_blkpg_ioctl_arg blkpg;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300209
210 tprints(", ");
211 if (!umove_or_printaddr(tcp, arg, &blkpg))
212 print_blkpg_req(tcp, &blkpg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000213 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300214 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000215
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000216 case BLKTRACESETUP:
217 if (entering(tcp)) {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000218 struct_blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300219
220 tprints(", ");
221 if (umove_or_printaddr(tcp, arg, &buts))
222 break;
223 tprintf("{act_mask=%u, buf_size=%u, "
224 "buf_nr=%u, start_lba=%" PRIu64 ", "
225 "end_lba=%" PRIu64 ", pid=%u",
226 (unsigned)buts.act_mask, buts.buf_size,
227 buts.buf_nr, buts.start_lba,
228 buts.end_lba, buts.pid);
229 return 1;
230 } else {
Dmitry V. Levin37d1b3d2016-05-26 10:43:51 +0000231 struct_blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300232
Dmitry V. Levin0bea5282016-05-26 10:04:39 +0000233 if (!syserror(tcp) && !umove(tcp, arg, &buts)) {
234 tprints(", name=");
235 print_quoted_string(buts.name, sizeof(buts.name),
236 QUOTE_0_TERMINATED);
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000237 }
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300238 tprints("}");
239 break;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000240 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000241
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300242 /* No arguments */
243 case BLKRRPART:
244 case BLKFLSBUF:
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000245 case BLKTRACESTART:
246 case BLKTRACESTOP:
247 case BLKTRACETEARDOWN:
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000248 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300249 default:
250 return RVAL_DECODED;
251 }
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000252
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300253 return RVAL_DECODED | 1;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000254}