blob: 1e02fa71bf30f51254710a6c6cac8fc42357365f [file] [log] [blame]
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +00001/*
2 * Copyright (c) 2009, 2010 Jeff Mahoney <jeffm@suse.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "defs.h"
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000029#include <linux/blkpg.h>
30#include <linux/fs.h>
31#include <linux/hdreg.h>
32
33/* ioctls <= 114 are present in Linux 2.4. The following ones have been
34 * added since then and headers containing them may not be available on
35 * every system. */
36
37#define BLKTRACE_BDEV_SIZE 32
38struct blk_user_trace_setup {
39 char name[BLKTRACE_BDEV_SIZE]; /* output */
40 uint16_t act_mask; /* input */
41 uint32_t buf_size; /* input */
42 uint32_t buf_nr; /* input */
43 uint64_t start_lba;
44 uint64_t end_lba;
45 uint32_t pid;
46};
47
48#ifndef BLKTRACESETUP
Dmitry V. Levina0beac12015-07-05 15:15:03 +030049# define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000050#endif
51#ifndef BLKTRACESTART
Dmitry V. Levina0beac12015-07-05 15:15:03 +030052# define BLKTRACESTART _IO(0x12,116)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000053#endif
Dmitry V. Levin4cee0af2011-04-07 19:58:10 +000054#ifndef BLKTRACESTOP
Dmitry V. Levina0beac12015-07-05 15:15:03 +030055# define BLKTRACESTOP _IO(0x12,117)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000056#endif
57#ifndef BLKTRACETEARDOWN
Dmitry V. Levina0beac12015-07-05 15:15:03 +030058# define BLKTRACETEARDOWN _IO(0x12,118)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000059#endif
60#ifndef BLKDISCARD
Dmitry V. Levina0beac12015-07-05 15:15:03 +030061# define BLKDISCARD _IO(0x12,119)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000062#endif
63#ifndef BLKIOMIN
Dmitry V. Levina0beac12015-07-05 15:15:03 +030064# define BLKIOMIN _IO(0x12,120)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000065#endif
66#ifndef BLKIOOPT
Dmitry V. Levina0beac12015-07-05 15:15:03 +030067# define BLKIOOPT _IO(0x12,121)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000068#endif
69#ifndef BLKALIGNOFF
Dmitry V. Levina0beac12015-07-05 15:15:03 +030070# define BLKALIGNOFF _IO(0x12,122)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000071#endif
72#ifndef BLKPBSZGET
Dmitry V. Levina0beac12015-07-05 15:15:03 +030073# define BLKPBSZGET _IO(0x12,123)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000074#endif
75#ifndef BLKDISCARDZEROES
Dmitry V. Levina0beac12015-07-05 15:15:03 +030076# define BLKDISCARDZEROES _IO(0x12,124)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000077#endif
78#ifndef BLKSECDISCARD
Dmitry V. Levina0beac12015-07-05 15:15:03 +030079# define BLKSECDISCARD _IO(0x12,125)
80#endif
81#ifndef BLKROTATIONAL
82# define BLKROTATIONAL _IO(0x12,126)
83#endif
84#ifndef BLKZEROOUT
85# define BLKZEROOUT _IO(0x12,127)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000086#endif
87
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000088#include "xlat/blkpg_ops.h"
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000089
90static void
Dmitry V. Levina0beac12015-07-05 15:15:03 +030091print_blkpg_req(struct tcb *tcp, const struct blkpg_ioctl_arg *blkpg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000092{
93 struct blkpg_partition p;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000094
Denys Vlasenko60fe8c12011-09-01 10:00:28 +020095 tprints("{");
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +000096 printxval(blkpg_ops, blkpg->op, "BLKPG_???");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +000097
Dmitry V. Levina0beac12015-07-05 15:15:03 +030098 tprintf(", flags=%d, datalen=%d, data=",
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +000099 blkpg->flags, blkpg->datalen);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000100
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300101 if (!umove_or_printaddr(tcp, (long) blkpg->data, &p)) {
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000102 tprintf("{start=%lld, length=%lld, pno=%d, devname=",
103 p.start, p.length, p.pno);
104 print_quoted_string(p.devname, sizeof(p.devname),
105 QUOTE_0_TERMINATED);
106 tprints(", volname=");
107 print_quoted_string(p.volname, sizeof(p.volname),
108 QUOTE_0_TERMINATED);
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300109 tprints("}");
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000110 }
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300111 tprints("}");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000112}
113
114int
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300115block_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000116{
117 switch (code) {
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000118 /* take arg as a value, not as a pointer */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000119 case BLKRASET:
120 case BLKFRASET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300121 tprintf(", %lu", arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000122 break;
123
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000124 /* take a signed int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000125 case BLKROSET:
126 case BLKBSZSET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300127 tprints(", ");
128 printnum_int(tcp, arg, "%d");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000129 break;
130
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300131 /* return an unsigned short */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000132 case BLKSECTGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300133 case BLKROTATIONAL:
134 if (entering(tcp))
135 return 0;
136 tprints(", ");
137 printnum_short(tcp, arg, "%hu");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000138 break;
139
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000140 /* return a signed int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000141 case BLKROGET:
142 case BLKBSZGET:
143 case BLKSSZGET:
144 case BLKALIGNOFF:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300145 if (entering(tcp))
146 return 0;
147 tprints(", ");
148 printnum_int(tcp, arg, "%d");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000149 break;
150
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000151 /* return an unsigned int */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000152 case BLKPBSZGET:
153 case BLKIOMIN:
154 case BLKIOOPT:
155 case BLKDISCARDZEROES:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300156 if (entering(tcp))
157 return 0;
158 tprints(", ");
159 printnum_int(tcp, arg, "%u");
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000160 break;
161
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000162 /* return a signed long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000163 case BLKRAGET:
164 case BLKFRAGET:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300165 if (entering(tcp))
166 return 0;
167 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000168 printnum_slong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000169 break;
170
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000171 /* returns an unsigned long */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000172 case BLKGETSIZE:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300173 if (entering(tcp))
174 return 0;
175 tprints(", ");
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000176 printnum_ulong(tcp, arg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000177 break;
178
Dmitry V. Levin25caa312011-08-16 21:36:16 +0000179#ifdef HAVE_BLKGETSIZE64
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300180 /* returns an uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000181 case BLKGETSIZE64:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300182 if (entering(tcp))
183 return 0;
184 tprints(", ");
185 printnum_int64(tcp, arg, "%" PRIu64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000186 break;
Denys Vlasenko5bd67c82011-08-15 11:36:09 +0200187#endif
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000188
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300189 /* takes a pair of uint64_t */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000190 case BLKDISCARD:
191 case BLKSECDISCARD:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300192 case BLKZEROOUT:
193 tprints(", ");
194 printpair_int64(tcp, arg, "%" PRIx64);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000195 break;
196
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300197 /* More complex types */
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000198 case HDIO_GETGEO:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300199 if (entering(tcp))
200 return 0;
201 else {
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000202 struct hd_geometry geo;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300203
204 tprints(", ");
205 if (!umove_or_printaddr(tcp, arg, &geo))
206 tprintf("{heads=%u, sectors=%u, "
Denys Vlasenko61d62cf2012-04-16 18:12:27 +0200207 "cylinders=%u, start=%lu}",
208 (unsigned)geo.heads,
209 (unsigned)geo.sectors,
210 (unsigned)geo.cylinders,
211 geo.start);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000212 }
213 break;
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000214
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300215 case BLKPG: {
216 struct blkpg_ioctl_arg blkpg;
217
218 tprints(", ");
219 if (!umove_or_printaddr(tcp, arg, &blkpg))
220 print_blkpg_req(tcp, &blkpg);
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000221 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300222 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000223
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000224 case BLKTRACESETUP:
225 if (entering(tcp)) {
226 struct blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300227
228 tprints(", ");
229 if (umove_or_printaddr(tcp, arg, &buts))
230 break;
231 tprintf("{act_mask=%u, buf_size=%u, "
232 "buf_nr=%u, start_lba=%" PRIu64 ", "
233 "end_lba=%" PRIu64 ", pid=%u",
234 (unsigned)buts.act_mask, buts.buf_size,
235 buts.buf_nr, buts.start_lba,
236 buts.end_lba, buts.pid);
237 return 1;
238 } else {
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000239 struct blk_user_trace_setup buts;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300240
241 if (syserror(tcp)) {
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000242 tprints("}");
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300243 break;
Dmitry V. Levin0a870582015-01-25 01:04:01 +0000244 }
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300245 tprints(", ");
246 if (umove(tcp, arg, &buts) < 0) {
247 tprints("???}");
248 break;
249 }
250 tprints(", name=");
251 print_quoted_string(buts.name, sizeof(buts.name),
252 QUOTE_0_TERMINATED);
253 tprints("}");
254 break;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000255 }
Dmitry V. Levinbe284ca2011-01-16 23:07:51 +0000256
Mike Frysinger5b886082014-11-21 16:13:16 -0500257#ifdef FITRIM
258 /* First seen in linux-2.6.37 */
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300259 case FITRIM: {
260 struct fstrim_range fstrim;
261
262 tprints(", ");
263 if (!umove_or_printaddr(tcp, arg, &fstrim))
264 tprintf("{start=%#" PRIx64 ", "
265 "len=%#" PRIx64 ", "
266 "minlen=%#" PRIx64 "}",
267 (uint64_t) fstrim.start,
268 (uint64_t) fstrim.len,
269 (uint64_t) fstrim.minlen);
Mike Frysinger5b886082014-11-21 16:13:16 -0500270 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300271 }
Mike Frysinger5b886082014-11-21 16:13:16 -0500272#endif
273
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300274 /* No arguments */
275 case BLKRRPART:
276 case BLKFLSBUF:
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000277 case BLKTRACESTART:
278 case BLKTRACESTOP:
279 case BLKTRACETEARDOWN:
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300280#ifdef FIFREEZE
281 case FIFREEZE:
282 case FITHAW:
283#endif
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000284 break;
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300285 default:
286 return RVAL_DECODED;
287 }
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000288
Dmitry V. Levina0beac12015-07-05 15:15:03 +0300289 return RVAL_DECODED | 1;
Dmitry V. Levin4ef6db42011-01-15 20:15:31 +0000290}