Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

block.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright (c) 2009, 2010 Jeff Mahoney <jeffm@suse.com>
  3. * Copyright (c) 2011-2016 Dmitry V. Levin <ldv@altlinux.org>
  4. * Copyright (c) 2011-2018 The strace developers.
  5. * All rights reserved.
  6. *
  7. * SPDX-License-Identifier: LGPL-2.1-or-later
  8. */
  9. #include "defs.h"
  10. #include DEF_MPERS_TYPE(struct_blk_user_trace_setup)
  11. #include DEF_MPERS_TYPE(struct_blkpg_ioctl_arg)
  12. #include DEF_MPERS_TYPE(struct_blkpg_partition)
  13. #include <linux/ioctl.h>
  14. #include <linux/fs.h>
  15. typedef struct {
  16. int op;
  17. int flags;
  18. int datalen;
  19. void *data;
  20. } struct_blkpg_ioctl_arg;
  21. #define BLKPG_DEVNAMELTH 64
  22. #define BLKPG_VOLNAMELTH 64
  23. typedef struct {
  24. int64_t start; /* starting offset in bytes */
  25. int64_t length; /* length in bytes */
  26. int pno; /* partition number */
  27. char devname[BLKPG_DEVNAMELTH]; /* partition name, like sda5 or c0d1p2,
  28. to be used in kernel messages */
  29. char volname[BLKPG_VOLNAMELTH]; /* volume label */
  30. } struct_blkpg_partition;
  31. #define BLKTRACE_BDEV_SIZE 32
  32. typedef struct blk_user_trace_setup {
  33. char name[BLKTRACE_BDEV_SIZE]; /* output */
  34. uint16_t act_mask; /* input */
  35. uint32_t buf_size; /* input */
  36. uint32_t buf_nr; /* input */
  37. uint64_t start_lba;
  38. uint64_t end_lba;
  39. uint32_t pid;
  40. } struct_blk_user_trace_setup;
  41. /* Provide fall-back definitions for BLK* ioctls */
  42. #define XLAT_MACROS_ONLY
  43. #include "xlat/block_ioctl_cmds.h"
  44. #undef XLAT_MACROS_ONLY
  45. #include MPERS_DEFS
  46. #include "print_fields.h"
  47. #include "xlat/blkpg_ops.h"
  48. static void
  49. print_blkpg_req(struct tcb *tcp, const struct_blkpg_ioctl_arg *blkpg)
  50. {
  51. struct_blkpg_partition p;
  52. PRINT_FIELD_XVAL("{", *blkpg, op, blkpg_ops, "BLKPG_???");
  53. PRINT_FIELD_D(", ", *blkpg, flags);
  54. PRINT_FIELD_D(", ", *blkpg, datalen);
  55. tprints(", data=");
  56. if (!umove_or_printaddr(tcp, ptr_to_kulong(blkpg->data), &p)) {
  57. PRINT_FIELD_D("{", p, start);
  58. PRINT_FIELD_D(", ", p, length);
  59. PRINT_FIELD_D(", ", p, pno);
  60. PRINT_FIELD_CSTRING(", ", p, devname);
  61. PRINT_FIELD_CSTRING(", ", p, volname);
  62. tprints("}");
  63. }
  64. tprints("}");
  65. }
  66. MPERS_PRINTER_DECL(int, block_ioctl, struct tcb *const tcp,
  67. const unsigned int code, const kernel_ulong_t arg)
  68. {
  69. switch (code) {
  70. /* take arg as a value, not as a pointer */
  71. case BLKRASET:
  72. case BLKFRASET:
  73. tprintf(", %" PRI_klu, arg);
  74. break;
  75. /* return an unsigned short */
  76. case BLKSECTGET:
  77. case BLKROTATIONAL:
  78. if (entering(tcp))
  79. return 0;
  80. tprints(", ");
  81. printnum_short(tcp, arg, "%hu");
  82. break;
  83. /* return a signed int */
  84. case BLKROGET:
  85. case BLKBSZGET:
  86. case BLKSSZGET:
  87. case BLKALIGNOFF:
  88. if (entering(tcp))
  89. return 0;
  90. ATTRIBUTE_FALLTHROUGH;
  91. /* take a signed int */
  92. case BLKROSET:
  93. case BLKBSZSET:
  94. tprints(", ");
  95. printnum_int(tcp, arg, "%d");
  96. break;
  97. /* return an unsigned int */
  98. case BLKPBSZGET:
  99. case BLKIOMIN:
  100. case BLKIOOPT:
  101. case BLKDISCARDZEROES:
  102. case BLKGETZONESZ:
  103. case BLKGETNRZONES:
  104. if (entering(tcp))
  105. return 0;
  106. tprints(", ");
  107. printnum_int(tcp, arg, "%u");
  108. break;
  109. /* return a signed long */
  110. case BLKRAGET:
  111. case BLKFRAGET:
  112. if (entering(tcp))
  113. return 0;
  114. tprints(", ");
  115. printnum_slong(tcp, arg);
  116. break;
  117. /* returns an unsigned long */
  118. case BLKGETSIZE:
  119. if (entering(tcp))
  120. return 0;
  121. tprints(", ");
  122. printnum_ulong(tcp, arg);
  123. break;
  124. /* returns an uint64_t */
  125. case BLKGETSIZE64:
  126. if (entering(tcp))
  127. return 0;
  128. tprints(", ");
  129. printnum_int64(tcp, arg, "%" PRIu64);
  130. break;
  131. /* takes a pair of uint64_t */
  132. case BLKDISCARD:
  133. case BLKSECDISCARD:
  134. case BLKZEROOUT:
  135. tprints(", ");
  136. printpair_int64(tcp, arg, "%" PRIu64);
  137. break;
  138. /* More complex types */
  139. case BLKPG: {
  140. struct_blkpg_ioctl_arg blkpg;
  141. tprints(", ");
  142. if (!umove_or_printaddr(tcp, arg, &blkpg))
  143. print_blkpg_req(tcp, &blkpg);
  144. break;
  145. }
  146. case BLKTRACESETUP:
  147. if (entering(tcp)) {
  148. struct_blk_user_trace_setup buts;
  149. tprints(", ");
  150. if (umove_or_printaddr(tcp, arg, &buts))
  151. break;
  152. PRINT_FIELD_U("{", buts, act_mask);
  153. PRINT_FIELD_U(", ", buts, buf_size);
  154. PRINT_FIELD_U(", ", buts, buf_nr);
  155. PRINT_FIELD_U(", ", buts, start_lba);
  156. PRINT_FIELD_U(", ", buts, end_lba);
  157. PRINT_FIELD_U(", ", buts, pid);
  158. return 0;
  159. } else {
  160. struct_blk_user_trace_setup buts;
  161. if (!syserror(tcp) && !umove(tcp, arg, &buts))
  162. PRINT_FIELD_CSTRING(", ", buts, name);
  163. tprints("}");
  164. break;
  165. }
  166. /* No arguments */
  167. case BLKRRPART:
  168. case BLKFLSBUF:
  169. case BLKTRACESTART:
  170. case BLKTRACESTOP:
  171. case BLKTRACETEARDOWN:
  172. break;
  173. default:
  174. return RVAL_DECODED;
  175. }
  176. return RVAL_IOCTL_DECODED;
  177. }