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.

btrfs.c 29KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250
  1. /*
  2. * Copyright (c) 2016 Jeff Mahoney <jeffm@suse.com>
  3. * Copyright (c) 2016-2019 The strace developers.
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: LGPL-2.1-or-later
  7. */
  8. #include "defs.h"
  9. #ifdef HAVE_LINUX_BTRFS_H
  10. # include DEF_MPERS_TYPE(struct_btrfs_ioctl_dev_replace_args)
  11. # include DEF_MPERS_TYPE(struct_btrfs_ioctl_send_args)
  12. # include DEF_MPERS_TYPE(struct_btrfs_ioctl_received_subvol_args)
  13. # include DEF_MPERS_TYPE(struct_btrfs_ioctl_vol_args_v2)
  14. # include <linux/btrfs.h>
  15. typedef struct btrfs_ioctl_dev_replace_args
  16. struct_btrfs_ioctl_dev_replace_args;
  17. typedef struct btrfs_ioctl_send_args
  18. struct_btrfs_ioctl_send_args;
  19. typedef struct btrfs_ioctl_received_subvol_args
  20. struct_btrfs_ioctl_received_subvol_args;
  21. typedef struct btrfs_ioctl_vol_args_v2
  22. struct_btrfs_ioctl_vol_args_v2;
  23. #endif /* HAVE_LINUX_BTRFS_H */
  24. #include MPERS_DEFS
  25. #ifdef HAVE_LINUX_BTRFS_H
  26. # include "print_fields.h"
  27. # include <linux/fs.h>
  28. /*
  29. * Prior to Linux 3.12, the BTRFS_IOC_DEFAULT_SUBVOL used u64 in
  30. * its definition, which isn't exported by the kernel.
  31. */
  32. typedef __u64 u64;
  33. # ifndef HAVE_STRUCT_BTRFS_IOCTL_FEATURE_FLAGS_COMPAT_FLAGS
  34. struct btrfs_ioctl_feature_flags {
  35. uint64_t compat_flags;
  36. uint64_t compat_ro_flags;
  37. uint64_t incompat_flags;
  38. };
  39. # endif
  40. # ifndef HAVE_STRUCT_BTRFS_IOCTL_DEFRAG_RANGE_ARGS_START
  41. struct btrfs_ioctl_defrag_range_args {
  42. uint64_t start;
  43. uint64_t len;
  44. uint64_t flags;
  45. uint32_t extent_thresh;
  46. uint32_t compress_type;
  47. uint32_t unused[4];
  48. };
  49. # endif
  50. # ifndef BTRFS_LABEL_SIZE
  51. # define BTRFS_LABEL_SIZE 256
  52. # endif
  53. # ifndef BTRFS_IOC_QUOTA_RESCAN
  54. struct btrfs_ioctl_quota_rescan_args {
  55. uint64_t flags, progress, reserved[6];
  56. };
  57. # define BTRFS_IOC_QUOTA_RESCAN _IOW(BTRFS_IOCTL_MAGIC, 44, \
  58. struct btrfs_ioctl_quota_rescan_args)
  59. # define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
  60. struct btrfs_ioctl_quota_rescan_args)
  61. # endif
  62. # ifndef BTRFS_IOC_QUOTA_RESCAN_WAIT
  63. # define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
  64. # endif
  65. # ifndef BTRFS_IOC_GET_FEATURES
  66. # define BTRFS_IOC_GET_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
  67. struct btrfs_ioctl_feature_flags)
  68. # define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, \
  69. struct btrfs_ioctl_feature_flags[2])
  70. # define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, \
  71. struct btrfs_ioctl_feature_flags[3])
  72. # endif
  73. # ifndef BTRFS_IOC_TREE_SEARCH_V2
  74. # define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \
  75. struct btrfs_ioctl_search_args_v2)
  76. struct btrfs_ioctl_search_args_v2 {
  77. struct btrfs_ioctl_search_key key; /* in/out - search parameters */
  78. uint64_t buf_size; /* in - size of buffer
  79. * out - on EOVERFLOW: needed size
  80. * to store item */
  81. uint64_t buf[0]; /* out - found items */
  82. };
  83. # endif
  84. # include "xlat/btrfs_balance_args.h"
  85. # include "xlat/btrfs_balance_ctl_cmds.h"
  86. # include "xlat/btrfs_balance_flags.h"
  87. # include "xlat/btrfs_balance_state.h"
  88. # include "xlat/btrfs_compress_types.h"
  89. # include "xlat/btrfs_cont_reading_from_srcdev_mode.h"
  90. # include "xlat/btrfs_defrag_flags.h"
  91. # include "xlat/btrfs_dev_replace_cmds.h"
  92. # include "xlat/btrfs_dev_replace_results.h"
  93. # include "xlat/btrfs_dev_replace_state.h"
  94. # include "xlat/btrfs_dev_stats_flags.h"
  95. # include "xlat/btrfs_dev_stats_values.h"
  96. # include "xlat/btrfs_features_compat.h"
  97. # include "xlat/btrfs_features_compat_ro.h"
  98. # include "xlat/btrfs_features_incompat.h"
  99. # include "xlat/btrfs_key_types.h"
  100. # include "xlat/btrfs_logical_ino_args_flags.h"
  101. # include "xlat/btrfs_qgroup_ctl_cmds.h"
  102. # include "xlat/btrfs_qgroup_inherit_flags.h"
  103. # include "xlat/btrfs_qgroup_limit_flags.h"
  104. # include "xlat/btrfs_qgroup_status_flags.h"
  105. # include "xlat/btrfs_scrub_flags.h"
  106. # include "xlat/btrfs_send_flags.h"
  107. # include "xlat/btrfs_snap_flags_v2.h"
  108. # include "xlat/btrfs_space_info_flags.h"
  109. # include "xlat/btrfs_tree_objectids.h"
  110. static void
  111. btrfs_print_balance_args(const char *name, const struct btrfs_balance_args *bba)
  112. {
  113. tprintf(", %s=", name);
  114. PRINT_FIELD_FLAGS("{", *bba, profiles, btrfs_space_info_flags,
  115. "BTRFS_BLOCK_GROUP_???");
  116. PRINT_FIELD_U64(", ", *bba, usage);
  117. PRINT_FIELD_DEV(", ", *bba, devid);
  118. PRINT_FIELD_U64(", ", *bba, pstart);
  119. PRINT_FIELD_U64(", ", *bba, pend);
  120. PRINT_FIELD_U64(", ", *bba, vstart);
  121. PRINT_FIELD_U64(", ", *bba, vend);
  122. PRINT_FIELD_U64(", ", *bba, target);
  123. PRINT_FIELD_FLAGS(", ", *bba, flags, btrfs_balance_args,
  124. "BTRFS_BALANCE_ARGS_???");
  125. tprints("}");
  126. }
  127. static void
  128. btrfs_print_balance(struct tcb *const tcp, const kernel_ulong_t arg, bool out)
  129. {
  130. struct btrfs_ioctl_balance_args balance_args;
  131. if (umove_or_printaddr(tcp, arg, &balance_args))
  132. return;
  133. PRINT_FIELD_FLAGS("{", balance_args, flags, btrfs_balance_flags,
  134. "BTRFS_BALANCE_???");
  135. if (out)
  136. PRINT_FIELD_FLAGS(", ", balance_args, state,
  137. btrfs_balance_state,
  138. "BTRFS_BALANCE_STATE_???");
  139. if (balance_args.flags & BTRFS_BALANCE_DATA)
  140. btrfs_print_balance_args("data", &balance_args.data);
  141. if (balance_args.flags & BTRFS_BALANCE_METADATA)
  142. btrfs_print_balance_args("meta", &balance_args.meta);
  143. if (balance_args.flags & BTRFS_BALANCE_SYSTEM)
  144. btrfs_print_balance_args("sys", &balance_args.sys);
  145. tprints("}");
  146. }
  147. static void
  148. btrfs_print_features(const struct btrfs_ioctl_feature_flags *flags)
  149. {
  150. PRINT_FIELD_FLAGS("{", *flags, compat_flags, btrfs_features_compat,
  151. "BTRFS_FEATURE_COMPAT_???");
  152. PRINT_FIELD_FLAGS(", ", *flags, compat_ro_flags,
  153. btrfs_features_compat_ro,
  154. "BTRFS_FEATURE_COMPAT_RO_???");
  155. PRINT_FIELD_FLAGS(", ", *flags, incompat_flags, btrfs_features_incompat,
  156. "BTRFS_FEATURE_INCOMPAT_???");
  157. tprints("}");
  158. }
  159. static void
  160. btrfs_print_qgroup_limit(const struct btrfs_qgroup_limit *lim)
  161. {
  162. PRINT_FIELD_FLAGS(", lim={", *lim, flags, btrfs_qgroup_limit_flags,
  163. "BTRFS_QGROUP_LIMIT_???");
  164. PRINT_FIELD_U(", ", *lim, max_rfer);
  165. PRINT_FIELD_U(", ", *lim, max_excl);
  166. PRINT_FIELD_U(", ", *lim, rsv_rfer);
  167. PRINT_FIELD_U(", ", *lim, rsv_excl);
  168. tprints("}");
  169. }
  170. # define btrfs_print_key_type(prefix_, where_, field_) \
  171. PRINT_FIELD_XVAL_U((prefix_), (where_), field_, btrfs_key_types, NULL)
  172. # define btrfs_print_objectid(prefix_, where_, field_) \
  173. PRINT_FIELD_XVAL_U((prefix_), (where_), field_, btrfs_tree_objectids, \
  174. NULL)
  175. static void
  176. btrfs_print_data_container_header(const struct btrfs_data_container *container)
  177. {
  178. PRINT_FIELD_U("{", *container, bytes_left);
  179. PRINT_FIELD_U(", ", *container, bytes_missing);
  180. PRINT_FIELD_U(", ", *container, elem_cnt);
  181. PRINT_FIELD_U(", ", *container, elem_missed);
  182. }
  183. static void
  184. btrfs_print_data_container_footer(void)
  185. {
  186. tprints("}");
  187. }
  188. static bool
  189. print_btrfs_data_container_logical_ino(struct tcb *tcp, void *elem_buf,
  190. size_t elem_size, void *data)
  191. {
  192. const struct {
  193. uint64_t inum;
  194. uint64_t offset;
  195. uint64_t root;
  196. } *const record = elem_buf;
  197. PRINT_FIELD_U("{", *record, inum);
  198. PRINT_FIELD_U(", ", *record, offset);
  199. PRINT_FIELD_U(", ", *record, root);
  200. tprints("}");
  201. return true;
  202. }
  203. static void
  204. btrfs_print_logical_ino_container(struct tcb *tcp,
  205. const uint64_t inodes_addr)
  206. {
  207. struct btrfs_data_container container;
  208. if (umove_or_printaddr(tcp, inodes_addr, &container))
  209. return;
  210. btrfs_print_data_container_header(&container);
  211. if (abbrev(tcp)) {
  212. tprints(", ...");
  213. } else {
  214. const uint64_t val_addr =
  215. inodes_addr + offsetof(typeof(container), val);
  216. uint64_t record[3];
  217. tprints(", val=");
  218. print_array(tcp, val_addr, container.elem_cnt / 3,
  219. record, sizeof(record),
  220. tfetch_mem,
  221. print_btrfs_data_container_logical_ino, 0);
  222. }
  223. btrfs_print_data_container_footer();
  224. }
  225. static bool
  226. print_btrfs_data_container_ino_path(struct tcb *tcp, void *elem_buf,
  227. size_t elem_size, void *data)
  228. {
  229. const uint64_t *const offset = elem_buf;
  230. const uint64_t *const val_addr = data;
  231. printpath(tcp, *val_addr + *offset);
  232. return true;
  233. }
  234. static void
  235. btrfs_print_ino_path_container(struct tcb *tcp,
  236. const uint64_t fspath_addr)
  237. {
  238. struct btrfs_data_container container;
  239. if (umove_or_printaddr(tcp, fspath_addr, &container))
  240. return;
  241. btrfs_print_data_container_header(&container);
  242. if (abbrev(tcp)) {
  243. tprints(", ...");
  244. } else {
  245. uint64_t val_addr =
  246. fspath_addr + offsetof(typeof(container), val);
  247. uint64_t offset;
  248. tprints(", val=");
  249. print_array(tcp, val_addr, container.elem_cnt,
  250. &offset, sizeof(offset),
  251. tfetch_mem,
  252. print_btrfs_data_container_ino_path, &val_addr);
  253. }
  254. btrfs_print_data_container_footer();
  255. }
  256. static void
  257. btrfs_print_qgroup_inherit(struct tcb *const tcp, const kernel_ulong_t qgi_addr)
  258. {
  259. struct btrfs_qgroup_inherit inherit;
  260. if (umove_or_printaddr(tcp, qgi_addr, &inherit))
  261. return;
  262. PRINT_FIELD_FLAGS("{", inherit, flags, btrfs_qgroup_inherit_flags,
  263. "BTRFS_QGROUP_INHERIT_???");
  264. PRINT_FIELD_U(", ", inherit, num_qgroups);
  265. PRINT_FIELD_U(", ", inherit, num_ref_copies);
  266. PRINT_FIELD_U(", ", inherit, num_excl_copies);
  267. btrfs_print_qgroup_limit(&inherit.lim);
  268. if (abbrev(tcp)) {
  269. tprints(", ...");
  270. } else {
  271. uint64_t record;
  272. tprints(", qgroups=");
  273. print_array(tcp, qgi_addr + offsetof(typeof(inherit), qgroups),
  274. inherit.num_qgroups, &record, sizeof(record),
  275. tfetch_mem, print_uint64_array_member, 0);
  276. }
  277. tprints("}");
  278. }
  279. static void
  280. btrfs_print_tree_search(struct tcb *tcp, struct btrfs_ioctl_search_key *key,
  281. uint64_t buf_addr, uint64_t buf_size, bool print_size)
  282. {
  283. if (entering(tcp)) {
  284. btrfs_print_objectid("{key={", *key, tree_id);
  285. if (key->min_objectid != BTRFS_FIRST_FREE_OBJECTID ||
  286. !abbrev(tcp))
  287. btrfs_print_objectid(", ", *key, min_objectid);
  288. if (key->max_objectid != BTRFS_LAST_FREE_OBJECTID ||
  289. !abbrev(tcp))
  290. btrfs_print_objectid(", ", *key, max_objectid);
  291. PRINT_FIELD_U64(", ", *key, min_offset);
  292. PRINT_FIELD_U64(", ", *key, max_offset);
  293. PRINT_FIELD_U64(", ", *key, min_transid);
  294. PRINT_FIELD_U64(", ", *key, max_transid);
  295. btrfs_print_key_type(", ", *key, min_type);
  296. btrfs_print_key_type(", ", *key, max_type);
  297. PRINT_FIELD_U(", ", *key, nr_items);
  298. tprints("}");
  299. if (print_size)
  300. tprintf(", buf_size=%" PRIu64, buf_size);
  301. tprints("}");
  302. } else {
  303. PRINT_FIELD_U("{key={", *key, nr_items);
  304. tprints("}");
  305. if (print_size)
  306. tprintf(", buf_size=%" PRIu64, buf_size);
  307. if (abbrev(tcp)) {
  308. tprints(", ...");
  309. } else {
  310. uint64_t i;
  311. uint64_t off = 0;
  312. tprints(", buf=[");
  313. for (i = 0; i < key->nr_items; i++) {
  314. struct btrfs_ioctl_search_header sh;
  315. uint64_t addr = buf_addr + off;
  316. if (i)
  317. tprints(", ");
  318. if (i > max_strlen) {
  319. tprints("...");
  320. break;
  321. }
  322. if (umove(tcp, addr, &sh)) {
  323. tprints("...");
  324. printaddr_comment(addr);
  325. break;
  326. }
  327. PRINT_FIELD_U("{", sh, transid);
  328. btrfs_print_objectid(", ", sh, objectid);
  329. PRINT_FIELD_U(", ", sh, offset);
  330. btrfs_print_key_type(", ", sh, type);
  331. PRINT_FIELD_U(", ", sh, len);
  332. tprints("}");
  333. off += sizeof(sh) + sh.len;
  334. }
  335. tprints("]");
  336. }
  337. tprints("}");
  338. }
  339. }
  340. static bool
  341. print_objectid_callback(struct tcb *tcp, void *elem_buf,
  342. size_t elem_size, void *data)
  343. {
  344. printxvals_ex(*(uint64_t *) elem_buf, NULL, XLAT_STYLE_FMT_U,
  345. btrfs_tree_objectids, NULL);
  346. return true;
  347. }
  348. static bool
  349. print_btrfs_ioctl_space_info(struct tcb *tcp, void *elem_buf,
  350. size_t elem_size, void *data)
  351. {
  352. const struct btrfs_ioctl_space_info *info = elem_buf;
  353. PRINT_FIELD_FLAGS("{", *info, flags, btrfs_space_info_flags,
  354. "BTRFS_SPACE_INFO_???");
  355. PRINT_FIELD_U(", ", *info, total_bytes);
  356. PRINT_FIELD_U(", ", *info, used_bytes);
  357. tprints("}");
  358. return true;
  359. }
  360. static void
  361. print_btrfs_timespec(const char *prefix, uint64_t sec, uint32_t nsec)
  362. {
  363. tprintf("%s{sec=%" PRIu64 ", nsec=%u}", prefix, sec, nsec);
  364. tprints_comment(sprinttime_nsec(sec, nsec));
  365. }
  366. MPERS_PRINTER_DECL(int, btrfs_ioctl,
  367. struct tcb *const tcp, const unsigned int code,
  368. const kernel_ulong_t arg)
  369. {
  370. switch (code) {
  371. /* Take no arguments; command only. */
  372. case BTRFS_IOC_TRANS_START:
  373. case BTRFS_IOC_TRANS_END:
  374. case BTRFS_IOC_SYNC:
  375. case BTRFS_IOC_SCRUB_CANCEL:
  376. case BTRFS_IOC_QUOTA_RESCAN_WAIT:
  377. /*
  378. * The codes for these ioctls are based on each accepting a
  379. * vol_args but none of them actually consume an argument.
  380. */
  381. case BTRFS_IOC_DEFRAG:
  382. case BTRFS_IOC_BALANCE:
  383. break;
  384. /* takes a signed int */
  385. case BTRFS_IOC_BALANCE_CTL:
  386. tprints(", ");
  387. printxval(btrfs_balance_ctl_cmds, arg, "BTRFS_BALANCE_CTL_???");
  388. break;
  389. /* returns a 64 */
  390. case BTRFS_IOC_START_SYNC: /* R */
  391. if (entering(tcp))
  392. return 0;
  393. ATTRIBUTE_FALLTHROUGH;
  394. /* takes a u64 */
  395. case BTRFS_IOC_DEFAULT_SUBVOL: /* W */
  396. case BTRFS_IOC_WAIT_SYNC: /* W */
  397. tprints(", ");
  398. printnum_int64(tcp, arg, "%" PRIu64);
  399. break;
  400. /* u64 but describe a flags bitfield; we can make that symbolic */
  401. case BTRFS_IOC_SUBVOL_GETFLAGS: { /* R */
  402. uint64_t flags;
  403. if (entering(tcp))
  404. return 0;
  405. tprints(", ");
  406. if (umove_or_printaddr(tcp, arg, &flags))
  407. break;
  408. printflags64(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
  409. break;
  410. }
  411. case BTRFS_IOC_SUBVOL_SETFLAGS: { /* W */
  412. uint64_t flags;
  413. tprints(", ");
  414. if (umove_or_printaddr(tcp, arg, &flags))
  415. break;
  416. printflags64(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
  417. break;
  418. }
  419. /* More complex types */
  420. case BTRFS_IOC_BALANCE_V2: /* RW */
  421. if (entering(tcp)) {
  422. tprints(", ");
  423. btrfs_print_balance(tcp, arg, false);
  424. return 0;
  425. }
  426. if (syserror(tcp))
  427. break;
  428. tprints(" => ");
  429. btrfs_print_balance(tcp, arg, true);
  430. break;
  431. case BTRFS_IOC_BALANCE_PROGRESS: /* R */
  432. if (entering(tcp))
  433. return 0;
  434. tprints(", ");
  435. btrfs_print_balance(tcp, arg, true);
  436. break;
  437. case BTRFS_IOC_DEFRAG_RANGE: { /* W */
  438. struct btrfs_ioctl_defrag_range_args args;
  439. tprints(", ");
  440. if (umove_or_printaddr(tcp, arg, &args))
  441. break;
  442. PRINT_FIELD_U("{", args, start);
  443. PRINT_FIELD_U64(", ", args, len);
  444. PRINT_FIELD_FLAGS(", ", args, flags, btrfs_defrag_flags,
  445. "BTRFS_DEFRAG_RANGE_???");
  446. PRINT_FIELD_U(", ", args, extent_thresh);
  447. PRINT_FIELD_XVAL(", ", args, compress_type,
  448. btrfs_compress_types, "BTRFS_COMPRESS_???");
  449. tprints("}");
  450. break;
  451. }
  452. case BTRFS_IOC_DEV_INFO: { /* RW */
  453. struct btrfs_ioctl_dev_info_args args;
  454. if (entering(tcp))
  455. tprints(", ");
  456. else if (syserror(tcp))
  457. break;
  458. else
  459. tprints(" => ");
  460. if (umove_or_printaddr(tcp, arg, &args))
  461. break;
  462. if (entering(tcp)) {
  463. PRINT_FIELD_DEV("{", args, devid);
  464. if (!IS_ARRAY_ZERO(args.uuid))
  465. PRINT_FIELD_UUID(", ", args, uuid);
  466. tprints("}");
  467. return 0;
  468. }
  469. tprints("{");
  470. if (!IS_ARRAY_ZERO(args.uuid)) {
  471. PRINT_FIELD_UUID("", args, uuid);
  472. tprints(", ");
  473. }
  474. PRINT_FIELD_U("", args, bytes_used);
  475. PRINT_FIELD_U(", ", args, total_bytes);
  476. PRINT_FIELD_CSTRING(", ", args, path);
  477. tprints("}");
  478. break;
  479. }
  480. case BTRFS_IOC_DEV_REPLACE: { /* RW */
  481. struct_btrfs_ioctl_dev_replace_args args;
  482. if (entering(tcp))
  483. tprints(", ");
  484. else if (syserror(tcp))
  485. break;
  486. else
  487. tprints(" => ");
  488. if (umove_or_printaddr(tcp, arg, &args))
  489. break;
  490. if (entering(tcp)) {
  491. PRINT_FIELD_XVAL("{", args, cmd, btrfs_dev_replace_cmds,
  492. "BTRFS_IOCTL_DEV_REPLACE_CMD_???");
  493. if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_START) {
  494. PRINT_FIELD_DEV(", start={", args.start,
  495. srcdevid);
  496. PRINT_FIELD_XVAL(", ", args.start,
  497. cont_reading_from_srcdev_mode,
  498. btrfs_cont_reading_from_srcdev_mode,
  499. "BTRFS_IOCTL_DEV_REPLACE_CONT_READING"
  500. "_FROM_SRCDEV_MODE_???");
  501. PRINT_FIELD_CSTRING(", ", args.start,
  502. srcdev_name);
  503. PRINT_FIELD_CSTRING(", ", args.start,
  504. tgtdev_name);
  505. tprints("}");
  506. }
  507. tprints("}");
  508. return 0;
  509. }
  510. PRINT_FIELD_XVAL("{", args, result, btrfs_dev_replace_results,
  511. "BTRFS_IOCTL_DEV_REPLACE_RESULT_???");
  512. if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS) {
  513. PRINT_FIELD_XVAL(", status={", args.status,
  514. replace_state, btrfs_dev_replace_state,
  515. "BTRFS_IOCTL_DEV_REPLACE_STATE_???");
  516. PRINT_FIELD_U(", ", args.status, progress_1000);
  517. if (args.status.progress_1000 <= 1000)
  518. tprintf_comment("%u.%u%%",
  519. (unsigned) args.status.progress_1000 / 10,
  520. (unsigned) args.status.progress_1000 % 10);
  521. PRINT_FIELD_U(", ", args.status, time_started);
  522. tprints_comment(sprinttime(args.status.time_started));
  523. PRINT_FIELD_U(", ", args.status, time_stopped);
  524. tprints_comment(sprinttime(args.status.time_stopped));
  525. PRINT_FIELD_U(", ", args.status, num_write_errors);
  526. PRINT_FIELD_U(", ", args.status,
  527. num_uncorrectable_read_errors);
  528. }
  529. tprints("}");
  530. break;
  531. }
  532. case BTRFS_IOC_GET_FEATURES: { /* R */
  533. struct btrfs_ioctl_feature_flags flags;
  534. if (entering(tcp))
  535. return 0;
  536. tprints(", ");
  537. if (umove_or_printaddr(tcp, arg, &flags))
  538. break;
  539. btrfs_print_features(&flags);
  540. break;
  541. }
  542. case BTRFS_IOC_SET_FEATURES: { /* W */
  543. struct btrfs_ioctl_feature_flags flarg[2];
  544. tprints(", ");
  545. if (umove_or_printaddr(tcp, arg, &flarg))
  546. break;
  547. tprints("[");
  548. btrfs_print_features(&flarg[0]);
  549. tprints(", ");
  550. btrfs_print_features(&flarg[1]);
  551. tprints("]");
  552. break;
  553. }
  554. case BTRFS_IOC_GET_SUPPORTED_FEATURES: { /* R */
  555. struct btrfs_ioctl_feature_flags flarg[3];
  556. if (entering(tcp))
  557. return 0;
  558. tprints(", ");
  559. if (umove_or_printaddr(tcp, arg, &flarg))
  560. break;
  561. tprints("[");
  562. btrfs_print_features(&flarg[0]);
  563. tprints_comment("supported");
  564. tprints(", ");
  565. btrfs_print_features(&flarg[1]);
  566. tprints_comment("safe to set");
  567. tprints(", ");
  568. btrfs_print_features(&flarg[2]);
  569. tprints_comment("safe to clear");
  570. tprints("]");
  571. break;
  572. }
  573. case BTRFS_IOC_FS_INFO: { /* R */
  574. struct btrfs_ioctl_fs_info_args args;
  575. uint32_t nodesize, sectorsize, clone_alignment;
  576. # ifndef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
  577. uint32_t *reserved32;
  578. # endif
  579. if (entering(tcp))
  580. return 0;
  581. tprints(", ");
  582. if (umove_or_printaddr(tcp, arg, &args))
  583. break;
  584. # ifdef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
  585. nodesize = args.nodesize,
  586. sectorsize = args.sectorsize,
  587. clone_alignment = args.clone_alignment;
  588. # else
  589. reserved32 = (void *) args.reserved;
  590. nodesize = reserved32[0];
  591. sectorsize = reserved32[1];
  592. clone_alignment = reserved32[2];
  593. # endif
  594. PRINT_FIELD_U("{", args, max_id);
  595. PRINT_FIELD_U(", ", args, num_devices);
  596. PRINT_FIELD_UUID(", ", args, fsid);
  597. tprintf(", nodesize=%u, sectorsize=%u, clone_alignment=%u",
  598. nodesize, sectorsize, clone_alignment);
  599. tprints("}");
  600. break;
  601. }
  602. case BTRFS_IOC_GET_DEV_STATS: { /* RW */
  603. struct btrfs_ioctl_get_dev_stats args;
  604. uint64_t i;
  605. if (entering(tcp))
  606. tprints(", ");
  607. else if (syserror(tcp))
  608. break;
  609. else
  610. tprints(" => ");
  611. if (umove_or_printaddr(tcp, arg, &args))
  612. break;
  613. tprints("{");
  614. if (entering(tcp)) {
  615. PRINT_FIELD_DEV("", args, devid);
  616. tprints(", ");
  617. }
  618. PRINT_FIELD_U("", args, nr_items);
  619. PRINT_FIELD_FLAGS(", ", args, flags, btrfs_dev_stats_flags,
  620. "BTRFS_DEV_STATS_???");
  621. if (entering(tcp)) {
  622. tprints("}");
  623. return 0;
  624. }
  625. /*
  626. * The structure has a 1k limit; Let's make sure we don't
  627. * go off into the middle of nowhere with a bad nr_items
  628. * value.
  629. */
  630. tprints(", [");
  631. for (i = 0; i < args.nr_items; i++) {
  632. if (i)
  633. tprints(", ");
  634. if (i >= ARRAY_SIZE(args.values)) {
  635. tprints("...");
  636. break;
  637. }
  638. tprints("[");
  639. printxval_u(btrfs_dev_stats_values, i, NULL);
  640. tprintf("] = %" PRI__u64, args.values[i]);
  641. }
  642. tprints("]}");
  643. break;
  644. }
  645. case BTRFS_IOC_INO_LOOKUP: { /* RW */
  646. struct btrfs_ioctl_ino_lookup_args args;
  647. if (entering(tcp))
  648. tprints(", ");
  649. else if (syserror(tcp))
  650. break;
  651. else
  652. tprints(" => ");
  653. if (umove_or_printaddr(tcp, arg, &args))
  654. break;
  655. if (entering(tcp)) {
  656. /* Use subvolume id of the containing root */
  657. if (args.treeid == 0)
  658. set_tcb_priv_ulong(tcp, 1);
  659. btrfs_print_objectid("{", args, treeid);
  660. btrfs_print_objectid(", ", args, objectid);
  661. tprints("}");
  662. return 0;
  663. }
  664. tprints("{");
  665. if (get_tcb_priv_ulong(tcp)) {
  666. btrfs_print_objectid("", args, treeid);
  667. tprints(", ");
  668. }
  669. PRINT_FIELD_CSTRING("", args, name);
  670. tprints("}");
  671. break;
  672. }
  673. case BTRFS_IOC_INO_PATHS: { /* RW */
  674. struct btrfs_ioctl_ino_path_args args;
  675. if (entering(tcp))
  676. tprints(", ");
  677. else if (syserror(tcp))
  678. break;
  679. else
  680. tprints(" => ");
  681. if (umove_or_printaddr(tcp, arg, &args))
  682. break;
  683. if (entering(tcp)) {
  684. PRINT_FIELD_U("{", args, inum);
  685. PRINT_FIELD_U(", ", args, size);
  686. PRINT_FIELD_ADDR64(", ", args, fspath);
  687. tprints("}");
  688. return 0;
  689. }
  690. tprints("{fspath=");
  691. btrfs_print_ino_path_container(tcp, args.fspath);
  692. tprints("}");
  693. break;
  694. }
  695. case BTRFS_IOC_LOGICAL_INO: { /* RW */
  696. struct btrfs_ioctl_logical_ino_args args;
  697. if (entering(tcp))
  698. tprints(", ");
  699. else if (syserror(tcp))
  700. break;
  701. else
  702. tprints(" => ");
  703. if (umove_or_printaddr(tcp, arg, &args))
  704. break;
  705. if (entering(tcp)) {
  706. PRINT_FIELD_U("{", args, logical);
  707. PRINT_FIELD_U(", ", args, size);
  708. if (!IS_ARRAY_ZERO(args.reserved)) {
  709. tprints(", reserved=[");
  710. for (size_t i = 0; i < 3; ++i)
  711. tprintf("%s%#" PRI__x64,
  712. i ? ", " : "",
  713. args.reserved[i]);
  714. tprints("]");
  715. }
  716. tprintf(", flags=");
  717. printflags64(btrfs_logical_ino_args_flags,
  718. # ifdef HAVE_STRUCT_BTRFS_IOCTL_LOGICAL_INO_ARGS_FLAGS
  719. args.flags
  720. # else
  721. args.reserved[3]
  722. # endif
  723. , "BTRFS_LOGICAL_INO_ARGS_???");
  724. PRINT_FIELD_ADDR64(", ", args, inodes);
  725. tprints("}");
  726. return 0;
  727. }
  728. tprints("{inodes=");
  729. btrfs_print_logical_ino_container(tcp, args.inodes);
  730. tprints("}");
  731. break;
  732. }
  733. case BTRFS_IOC_QGROUP_ASSIGN: { /* W */
  734. struct btrfs_ioctl_qgroup_assign_args args;
  735. tprints(", ");
  736. if (umove_or_printaddr(tcp, arg, &args))
  737. break;
  738. PRINT_FIELD_U("{", args, assign);
  739. PRINT_FIELD_U(", ", args, src);
  740. PRINT_FIELD_U(", ", args, dst);
  741. tprints("}");
  742. break;
  743. }
  744. case BTRFS_IOC_QGROUP_CREATE: { /* W */
  745. struct btrfs_ioctl_qgroup_create_args args;
  746. tprints(", ");
  747. if (umove_or_printaddr(tcp, arg, &args))
  748. break;
  749. PRINT_FIELD_U("{", args, create);
  750. PRINT_FIELD_U(", ", args, qgroupid);
  751. tprints("}");
  752. break;
  753. }
  754. case BTRFS_IOC_QGROUP_LIMIT: { /* R */
  755. struct btrfs_ioctl_qgroup_limit_args args;
  756. if (entering(tcp))
  757. return 0;
  758. tprints(", ");
  759. if (umove_or_printaddr(tcp, arg, &args))
  760. break;
  761. PRINT_FIELD_U("{", args, qgroupid);
  762. btrfs_print_qgroup_limit(&args.lim);
  763. tprints("}");
  764. break;
  765. }
  766. case BTRFS_IOC_QUOTA_CTL: { /* W */
  767. struct btrfs_ioctl_quota_ctl_args args;
  768. tprints(", ");
  769. if (umove_or_printaddr(tcp, arg, &args))
  770. break;
  771. PRINT_FIELD_XVAL("{", args, cmd, btrfs_qgroup_ctl_cmds,
  772. "BTRFS_QUOTA_CTL_???");
  773. tprints("}");
  774. break;
  775. }
  776. case BTRFS_IOC_QUOTA_RESCAN: { /* W */
  777. struct btrfs_ioctl_quota_rescan_args args;
  778. tprints(", ");
  779. if (umove_or_printaddr(tcp, arg, &args))
  780. break;
  781. PRINT_FIELD_U("{", args, flags);
  782. tprints("}");
  783. break;
  784. }
  785. case BTRFS_IOC_QUOTA_RESCAN_STATUS: { /* R */
  786. struct btrfs_ioctl_quota_rescan_args args;
  787. if (entering(tcp))
  788. return 0;
  789. tprints(", ");
  790. if (umove_or_printaddr(tcp, arg, &args))
  791. break;
  792. PRINT_FIELD_U("{", args, flags);
  793. btrfs_print_objectid(", ", args, progress);
  794. tprints("}");
  795. break;
  796. }
  797. case BTRFS_IOC_SET_RECEIVED_SUBVOL: { /* RW */
  798. struct_btrfs_ioctl_received_subvol_args args;
  799. if (entering(tcp))
  800. tprints(", ");
  801. else if (syserror(tcp))
  802. break;
  803. else
  804. tprints(" => ");
  805. if (umove_or_printaddr(tcp, arg, &args))
  806. break;
  807. if (entering(tcp)) {
  808. PRINT_FIELD_UUID("{", args, uuid);
  809. PRINT_FIELD_U(", ", args, stransid);
  810. print_btrfs_timespec(", stime=",
  811. args.stime.sec, args.stime.nsec);
  812. PRINT_FIELD_U(", ", args, flags);
  813. tprints("}");
  814. return 0;
  815. }
  816. PRINT_FIELD_U("{", args, rtransid);
  817. print_btrfs_timespec(", rtime=",
  818. args.rtime.sec, args.rtime.nsec);
  819. tprints("}");
  820. break;
  821. }
  822. case BTRFS_IOC_SCRUB: /* RW */
  823. case BTRFS_IOC_SCRUB_PROGRESS: { /* RW */
  824. struct btrfs_ioctl_scrub_args args;
  825. if (entering(tcp))
  826. tprints(", ");
  827. else if (syserror(tcp))
  828. break;
  829. else
  830. tprints(" => ");
  831. if (umove_or_printaddr(tcp, arg, &args))
  832. break;
  833. if (entering(tcp)) {
  834. PRINT_FIELD_DEV("{", args, devid);
  835. if (code == BTRFS_IOC_SCRUB) {
  836. PRINT_FIELD_U(", ", args, start);
  837. PRINT_FIELD_U64(", ", args, end);
  838. PRINT_FIELD_FLAGS(", ", args, flags,
  839. btrfs_scrub_flags,
  840. "BTRFS_SCRUB_???");
  841. }
  842. tprints("}");
  843. return 0;
  844. }
  845. PRINT_FIELD_U("{progress={", args.progress,
  846. data_extents_scrubbed);
  847. PRINT_FIELD_U(", ", args.progress, tree_extents_scrubbed);
  848. PRINT_FIELD_U(", ", args.progress, data_bytes_scrubbed);
  849. PRINT_FIELD_U(", ", args.progress, tree_bytes_scrubbed);
  850. PRINT_FIELD_U(", ", args.progress, read_errors);
  851. PRINT_FIELD_U(", ", args.progress, csum_errors);
  852. PRINT_FIELD_U(", ", args.progress, verify_errors);
  853. PRINT_FIELD_U(", ", args.progress, no_csum);
  854. PRINT_FIELD_U(", ", args.progress, csum_discards);
  855. PRINT_FIELD_U(", ", args.progress, super_errors);
  856. PRINT_FIELD_U(", ", args.progress, malloc_errors);
  857. PRINT_FIELD_U(", ", args.progress, uncorrectable_errors);
  858. PRINT_FIELD_U(", ", args.progress, corrected_errors);
  859. PRINT_FIELD_U(", ", args.progress, last_physical);
  860. PRINT_FIELD_U(", ", args.progress, unverified_errors);
  861. tprints("}}");
  862. break;
  863. }
  864. case BTRFS_IOC_TREE_SEARCH: { /* RW */
  865. struct btrfs_ioctl_search_args args;
  866. uint64_t buf_offset;
  867. if (entering(tcp))
  868. tprints(", ");
  869. else if (syserror(tcp))
  870. break;
  871. else
  872. tprints(" => ");
  873. if (umove_or_printaddr(tcp, arg, &args))
  874. break;
  875. buf_offset = offsetof(struct btrfs_ioctl_search_args, buf);
  876. btrfs_print_tree_search(tcp, &args.key, arg + buf_offset,
  877. sizeof(args.buf), false);
  878. if (entering(tcp))
  879. return 0;
  880. break;
  881. }
  882. case BTRFS_IOC_TREE_SEARCH_V2: { /* RW */
  883. struct btrfs_ioctl_search_args_v2 args;
  884. uint64_t buf_offset;
  885. if (entering(tcp))
  886. tprints(", ");
  887. else if (syserror(tcp)) {
  888. if (tcp->u_error == EOVERFLOW) {
  889. tprints(" => ");
  890. if (!umove_or_printaddr_ignore_syserror(tcp,
  891. arg, &args)) {
  892. PRINT_FIELD_U("{", args, buf_size);
  893. tprints("}");
  894. }
  895. }
  896. break;
  897. } else
  898. tprints(" => ");
  899. if (umove_or_printaddr(tcp, arg, &args))
  900. break;
  901. buf_offset = offsetof(struct btrfs_ioctl_search_args_v2, buf);
  902. btrfs_print_tree_search(tcp, &args.key, arg + buf_offset,
  903. args.buf_size, true);
  904. if (entering(tcp))
  905. return 0;
  906. break;
  907. }
  908. case BTRFS_IOC_SEND: { /* W */
  909. struct_btrfs_ioctl_send_args args;
  910. tprints(", ");
  911. if (umove_or_printaddr(tcp, arg, &args))
  912. break;
  913. PRINT_FIELD_FD("{", args, send_fd, tcp);
  914. PRINT_FIELD_U(", ", args, clone_sources_count);
  915. tprints(", clone_sources=");
  916. if (abbrev(tcp))
  917. printaddr((uintptr_t) args.clone_sources);
  918. else {
  919. uint64_t record;
  920. print_array(tcp, ptr_to_kulong(args.clone_sources),
  921. args.clone_sources_count,
  922. &record, sizeof(record),
  923. tfetch_mem,
  924. print_objectid_callback, 0);
  925. }
  926. btrfs_print_objectid(", ", args, parent_root);
  927. PRINT_FIELD_FLAGS(", ", args, flags, btrfs_send_flags,
  928. "BTRFS_SEND_FLAGS_???");
  929. tprints("}");
  930. break;
  931. }
  932. case BTRFS_IOC_SPACE_INFO: { /* RW */
  933. struct btrfs_ioctl_space_args args;
  934. if (entering(tcp))
  935. tprints(", ");
  936. else if (syserror(tcp))
  937. break;
  938. else
  939. tprints(" => ");
  940. if (umove_or_printaddr(tcp, arg, &args))
  941. break;
  942. if (entering(tcp)) {
  943. PRINT_FIELD_U("{", args, space_slots);
  944. tprints("}");
  945. return 0;
  946. }
  947. PRINT_FIELD_U("{", args, total_spaces);
  948. if (args.space_slots == 0 && args.total_spaces) {
  949. tprints("}");
  950. break;
  951. }
  952. if (abbrev(tcp)) {
  953. tprints(", ...");
  954. } else {
  955. struct btrfs_ioctl_space_info info;
  956. tprints(", spaces=");
  957. print_array(tcp, arg + offsetof(typeof(args), spaces),
  958. args.total_spaces,
  959. &info, sizeof(info), tfetch_mem,
  960. print_btrfs_ioctl_space_info, 0);
  961. }
  962. tprints("}");
  963. break;
  964. }
  965. case BTRFS_IOC_SNAP_CREATE:
  966. case BTRFS_IOC_RESIZE:
  967. case BTRFS_IOC_SCAN_DEV:
  968. # ifdef BTRFS_IOC_FORGET_DEV
  969. case BTRFS_IOC_FORGET_DEV:
  970. # endif
  971. case BTRFS_IOC_ADD_DEV:
  972. case BTRFS_IOC_RM_DEV:
  973. case BTRFS_IOC_SUBVOL_CREATE:
  974. case BTRFS_IOC_SNAP_DESTROY:
  975. case BTRFS_IOC_DEVICES_READY: { /* W */
  976. struct btrfs_ioctl_vol_args args;
  977. tprints(", ");
  978. if (umove_or_printaddr(tcp, arg, &args))
  979. break;
  980. PRINT_FIELD_FD("{", args, fd, tcp);
  981. PRINT_FIELD_CSTRING(", ", args, name);
  982. tprints("}");
  983. break;
  984. }
  985. case BTRFS_IOC_SNAP_CREATE_V2:
  986. case BTRFS_IOC_SUBVOL_CREATE_V2: { /* code is W, but is actually RW */
  987. struct_btrfs_ioctl_vol_args_v2 args;
  988. if (entering(tcp))
  989. tprints(", ");
  990. else if (syserror(tcp))
  991. break;
  992. else
  993. tprints(" => ");
  994. if (umove_or_printaddr(tcp, arg, &args))
  995. break;
  996. if (entering(tcp)) {
  997. PRINT_FIELD_FD("{", args, fd, tcp);
  998. PRINT_FIELD_FLAGS(", ", args, flags,
  999. btrfs_snap_flags_v2,
  1000. "BTRFS_SUBVOL_???");
  1001. if (args.flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
  1002. PRINT_FIELD_U(", ", args, size);
  1003. tprints(", qgroup_inherit=");
  1004. btrfs_print_qgroup_inherit(tcp,
  1005. ptr_to_kulong(args.qgroup_inherit));
  1006. }
  1007. PRINT_FIELD_CSTRING(", ", args, name);
  1008. tprints("}");
  1009. return 0;
  1010. }
  1011. PRINT_FIELD_U("{", args, transid);
  1012. tprints("}");
  1013. break;
  1014. }
  1015. case BTRFS_IOC_GET_FSLABEL: /* R */
  1016. if (entering(tcp))
  1017. return 0;
  1018. ATTRIBUTE_FALLTHROUGH;
  1019. case BTRFS_IOC_SET_FSLABEL: { /* W */
  1020. char label[BTRFS_LABEL_SIZE];
  1021. tprints(", ");
  1022. if (umove_or_printaddr(tcp, arg, &label))
  1023. break;
  1024. print_quoted_cstring(label, sizeof(label));
  1025. break;
  1026. }
  1027. case BTRFS_IOC_CLONE: /* FICLONE */
  1028. case BTRFS_IOC_CLONE_RANGE: /* FICLONERANGE */
  1029. # ifdef BTRFS_IOC_FILE_EXTENT_SAME
  1030. case BTRFS_IOC_FILE_EXTENT_SAME: /* FIDEDUPERANGE */
  1031. # endif
  1032. /*
  1033. * FICLONE, FICLONERANGE, and FIDEDUPERANGE started out as
  1034. * btrfs ioctls and the code was kept for the generic
  1035. * implementations. We use the BTRFS_* names here because
  1036. * they will be available on older systems.
  1037. */
  1038. return file_ioctl(tcp, code, arg);
  1039. default:
  1040. return RVAL_DECODED;
  1041. };
  1042. return RVAL_IOCTL_DECODED;
  1043. }
  1044. #endif /* HAVE_LINUX_BTRFS_H */