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.

1294 lines
28 KiB

  1. /*
  2. ISC License
  3. Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
  4. Permission to use, copy, modify, and/or distribute this software for any
  5. purpose with or without fee is hereby granted, provided that the above
  6. copyright notice and this permission notice appear in all copies.
  7. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. */
  15. #define _GNU_SOURCE
  16. #include "fuse_kernel.h"
  17. #include <errno.h>
  18. #include <fcntl.h>
  19. #include <inttypes.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. static FILE *g_OUTPUT = NULL;
  23. #define PARAM(inarg) (((char *)(inarg)) + sizeof(*(inarg)))
  24. static
  25. int
  26. debug_set_output_null()
  27. {
  28. g_OUTPUT = stderr;
  29. setvbuf(g_OUTPUT,NULL,_IOLBF,0);
  30. return 0;
  31. }
  32. static
  33. int
  34. debug_set_output_filepath(const char *filepath_)
  35. {
  36. FILE *tmp;
  37. tmp = fopen(filepath_,"a");
  38. if(tmp == NULL)
  39. return -errno;
  40. g_OUTPUT = tmp;
  41. setvbuf(g_OUTPUT,NULL,_IOLBF,0);
  42. return 0;
  43. }
  44. int
  45. debug_set_output(const char *filepath_)
  46. {
  47. if(filepath_ == NULL)
  48. return debug_set_output_null();
  49. return debug_set_output_filepath(filepath_);
  50. }
  51. static
  52. __attribute__((constructor))
  53. void
  54. debug_constructor(void)
  55. {
  56. debug_set_output(NULL);
  57. }
  58. static
  59. const
  60. char*
  61. open_accmode_to_str(const int flags_)
  62. {
  63. switch(flags_ & O_ACCMODE)
  64. {
  65. case O_RDWR:
  66. return "O_RDWR";
  67. case O_RDONLY:
  68. return "O_RDONLY";
  69. case O_WRONLY:
  70. return "O_WRONLY";
  71. }
  72. return "";
  73. }
  74. #define FUSE_WRITE_FLAG_CASE(X) case FUSE_WRITE_##X: return #X
  75. static
  76. const
  77. char*
  78. fuse_write_flag_to_str(const uint32_t offset_)
  79. {
  80. switch(1 << offset_)
  81. {
  82. FUSE_WRITE_FLAG_CASE(CACHE);
  83. FUSE_WRITE_FLAG_CASE(LOCKOWNER);
  84. FUSE_WRITE_FLAG_CASE(KILL_PRIV);
  85. }
  86. return NULL;
  87. }
  88. #undef FUSE_WRITE_FLAG_CASE
  89. #define OPEN_FLAG_CASE(X) case X: return #X
  90. static
  91. const
  92. char*
  93. open_flag_to_str(const uint64_t offset_)
  94. {
  95. switch(1 << offset_)
  96. {
  97. OPEN_FLAG_CASE(O_APPEND);
  98. OPEN_FLAG_CASE(O_ASYNC);
  99. OPEN_FLAG_CASE(O_CLOEXEC);
  100. OPEN_FLAG_CASE(O_CREAT);
  101. OPEN_FLAG_CASE(O_DIRECT);
  102. OPEN_FLAG_CASE(O_DIRECTORY);
  103. #ifdef O_DSYNC
  104. OPEN_FLAG_CASE(O_DSYNC);
  105. #endif
  106. OPEN_FLAG_CASE(O_EXCL);
  107. #ifdef O_LARGEFILE
  108. OPEN_FLAG_CASE(O_LARGEFILE);
  109. #endif
  110. #ifdef O_NOATIME
  111. OPEN_FLAG_CASE(O_NOATIME);
  112. #endif
  113. OPEN_FLAG_CASE(O_NOCTTY);
  114. OPEN_FLAG_CASE(O_NOFOLLOW);
  115. OPEN_FLAG_CASE(O_NONBLOCK);
  116. #ifdef O_PATH
  117. OPEN_FLAG_CASE(O_PATH);
  118. #endif
  119. OPEN_FLAG_CASE(O_SYNC);
  120. #ifdef O_TMPFILE
  121. OPEN_FLAG_CASE(O_TMPFILE);
  122. #endif
  123. OPEN_FLAG_CASE(O_TRUNC);
  124. }
  125. return NULL;
  126. }
  127. #undef OPEN_FLAG_CASE
  128. #define FUSE_INIT_FLAG_CASE(X) case FUSE_##X: return #X
  129. static
  130. const
  131. char*
  132. fuse_flag_to_str(const uint64_t offset_)
  133. {
  134. switch(1ULL << offset_)
  135. {
  136. FUSE_INIT_FLAG_CASE(ASYNC_READ);
  137. FUSE_INIT_FLAG_CASE(POSIX_LOCKS);
  138. FUSE_INIT_FLAG_CASE(FILE_OPS);
  139. FUSE_INIT_FLAG_CASE(ATOMIC_O_TRUNC);
  140. FUSE_INIT_FLAG_CASE(EXPORT_SUPPORT);
  141. FUSE_INIT_FLAG_CASE(BIG_WRITES);
  142. FUSE_INIT_FLAG_CASE(DONT_MASK);
  143. FUSE_INIT_FLAG_CASE(SPLICE_WRITE);
  144. FUSE_INIT_FLAG_CASE(SPLICE_MOVE);
  145. FUSE_INIT_FLAG_CASE(SPLICE_READ);
  146. FUSE_INIT_FLAG_CASE(FLOCK_LOCKS);
  147. FUSE_INIT_FLAG_CASE(HAS_IOCTL_DIR);
  148. FUSE_INIT_FLAG_CASE(AUTO_INVAL_DATA);
  149. FUSE_INIT_FLAG_CASE(DO_READDIRPLUS);
  150. FUSE_INIT_FLAG_CASE(READDIRPLUS_AUTO);
  151. FUSE_INIT_FLAG_CASE(ASYNC_DIO);
  152. FUSE_INIT_FLAG_CASE(WRITEBACK_CACHE);
  153. FUSE_INIT_FLAG_CASE(NO_OPEN_SUPPORT);
  154. FUSE_INIT_FLAG_CASE(PARALLEL_DIROPS);
  155. FUSE_INIT_FLAG_CASE(HANDLE_KILLPRIV);
  156. FUSE_INIT_FLAG_CASE(POSIX_ACL);
  157. FUSE_INIT_FLAG_CASE(ABORT_ERROR);
  158. FUSE_INIT_FLAG_CASE(MAX_PAGES);
  159. FUSE_INIT_FLAG_CASE(CACHE_SYMLINKS);
  160. FUSE_INIT_FLAG_CASE(NO_OPENDIR_SUPPORT);
  161. FUSE_INIT_FLAG_CASE(EXPLICIT_INVAL_DATA);
  162. FUSE_INIT_FLAG_CASE(MAP_ALIGNMENT);
  163. FUSE_INIT_FLAG_CASE(SUBMOUNTS);
  164. FUSE_INIT_FLAG_CASE(HANDLE_KILLPRIV_V2);
  165. FUSE_INIT_FLAG_CASE(SETXATTR_EXT);
  166. FUSE_INIT_FLAG_CASE(INIT_EXT);
  167. FUSE_INIT_FLAG_CASE(INIT_RESERVED);
  168. FUSE_INIT_FLAG_CASE(SECURITY_CTX);
  169. FUSE_INIT_FLAG_CASE(HAS_INODE_DAX);
  170. FUSE_INIT_FLAG_CASE(CREATE_SUPP_GROUP);
  171. FUSE_INIT_FLAG_CASE(HAS_EXPIRE_ONLY);
  172. FUSE_INIT_FLAG_CASE(DIRECT_IO_ALLOW_MMAP);
  173. }
  174. return NULL;
  175. }
  176. #undef FUSE_INIT_FLAG_CASE
  177. static
  178. void
  179. debug_open_flags(const uint32_t flags_)
  180. {
  181. fprintf(stderr,"%s, ",open_accmode_to_str(flags_));
  182. for(int i = 0; i < (sizeof(flags_) * 8); i++)
  183. {
  184. const char *str;
  185. if(!(flags_ & (1 << i)))
  186. continue;
  187. str = open_flag_to_str(i);
  188. if(str == NULL)
  189. continue;
  190. fprintf(stderr,"%s, ",str);
  191. }
  192. }
  193. #define FOPEN_FLAG_CASE(X) case FOPEN_##X: return #X
  194. static
  195. const
  196. char*
  197. fuse_fopen_flag_to_str(const uint32_t offset_)
  198. {
  199. switch(1 << offset_)
  200. {
  201. FOPEN_FLAG_CASE(DIRECT_IO);
  202. FOPEN_FLAG_CASE(KEEP_CACHE);
  203. FOPEN_FLAG_CASE(NONSEEKABLE);
  204. FOPEN_FLAG_CASE(CACHE_DIR);
  205. FOPEN_FLAG_CASE(STREAM);
  206. }
  207. return NULL;
  208. }
  209. #undef FOPEN_FLAG_CASE
  210. void
  211. debug_fuse_open_out(const struct fuse_open_out *arg_)
  212. {
  213. fprintf(stderr,
  214. "fuse_open_out:"
  215. " fh=0x%"PRIx64";"
  216. " open_flags=0x%X (",
  217. arg_->fh,
  218. arg_->open_flags);
  219. for(int i = 0; i < (sizeof(arg_->open_flags) * 8); i++)
  220. {
  221. const char *str;
  222. if(!(arg_->open_flags & (1 << i)))
  223. continue;
  224. str = fuse_fopen_flag_to_str(i);
  225. if(str == NULL)
  226. continue;
  227. fprintf(stderr,"%s,",str);
  228. }
  229. fprintf(stderr,");\n");
  230. }
  231. static
  232. void
  233. debug_fuse_lookup(const void *arg_)
  234. {
  235. const char *name = arg_;
  236. fprintf(g_OUTPUT,
  237. "fuse_lookup:"
  238. " name=%s;"
  239. "\n"
  240. ,
  241. name);
  242. }
  243. static
  244. void
  245. debug_fuse_getattr_in(const void *arg_)
  246. {
  247. const struct fuse_getattr_in *arg = arg_;
  248. fprintf(g_OUTPUT,
  249. "fuse_getattr_in:"
  250. " getattr_flags=0x%08X;"
  251. " fh=0x%"PRIx64";\n",
  252. arg->getattr_flags,
  253. arg->fh);
  254. }
  255. static
  256. void
  257. debug_fuse_setattr_in(const void *arg_)
  258. {
  259. const struct fuse_setattr_in *arg = arg_;
  260. fprintf(g_OUTPUT,
  261. "fuse_setattr_in:"
  262. " valid=%u;"
  263. " fh=0x%"PRIx64";"
  264. " size=%zu;"
  265. " lock_owner=%zu;"
  266. " atime=%zu;"
  267. " atimensec=%u;"
  268. " mtime=%zu;"
  269. " mtimensec=%u;"
  270. " ctime=%zu;"
  271. " ctimensec=%u;"
  272. " mode=%o;"
  273. " uid=%u;"
  274. " gid=%u;"
  275. "\n"
  276. ,
  277. arg->valid,
  278. arg->fh,
  279. arg->size,
  280. arg->lock_owner,
  281. arg->atime,
  282. arg->atimensec,
  283. arg->mtime,
  284. arg->mtimensec,
  285. arg->ctime,
  286. arg->ctimensec,
  287. arg->mode,
  288. arg->uid,
  289. arg->gid);
  290. }
  291. static
  292. void
  293. debug_fuse_access_in(const void *arg_)
  294. {
  295. const struct fuse_access_in *arg = arg_;
  296. fprintf(g_OUTPUT,
  297. "fuse_access_in:"
  298. " mask=0x%08X;"
  299. "\n"
  300. ,
  301. arg->mask);
  302. }
  303. static
  304. void
  305. debug_fuse_mknod_in(const void *arg_)
  306. {
  307. const struct fuse_mknod_in *arg = arg_;
  308. fprintf(g_OUTPUT,
  309. "fuse_mknod_in:"
  310. " mode=%o;"
  311. " rdev=0x%08X;"
  312. " umask=%o;"
  313. "\n"
  314. ,
  315. arg->mode,
  316. arg->rdev,
  317. arg->umask);
  318. }
  319. static
  320. void
  321. debug_fuse_mkdir_in(const void *arg_)
  322. {
  323. const struct fuse_mkdir_in *arg = arg_;
  324. fprintf(g_OUTPUT,
  325. "fuse_mkdir_in:"
  326. " mode=%o;"
  327. " umask=%o;"
  328. " name=%s;"
  329. "\n"
  330. ,
  331. arg->mode,
  332. arg->umask,
  333. PARAM(arg));
  334. }
  335. static
  336. void
  337. debug_fuse_unlink(const void *arg_)
  338. {
  339. const char *name = arg_;
  340. fprintf(g_OUTPUT,
  341. "fuse_unlink:"
  342. " name=%s;"
  343. "\n"
  344. ,
  345. name);
  346. }
  347. static
  348. void
  349. debug_fuse_rmdir(const void *arg_)
  350. {
  351. const char *name = arg_;
  352. fprintf(g_OUTPUT,
  353. "fuse_mkdir:"
  354. " name=%s;"
  355. "\n"
  356. ,
  357. name);
  358. }
  359. static
  360. void
  361. debug_fuse_symlink(const void *arg_)
  362. {
  363. const char *name;
  364. const char *linkname;
  365. name = arg_;
  366. linkname = (name + (strlen(name) + 1));
  367. fprintf(g_OUTPUT,
  368. "fuse_mkdir:"
  369. " linkname=%s;"
  370. " name=%s;"
  371. "\n"
  372. ,
  373. linkname,
  374. name);
  375. }
  376. static
  377. void
  378. debug_fuse_rename_in(const void *arg_)
  379. {
  380. const char *oldname;
  381. const char *newname;
  382. const struct fuse_rename_in *arg = arg_;
  383. oldname = PARAM(arg);
  384. newname = (oldname + strlen(oldname) + 1);
  385. fprintf(g_OUTPUT,
  386. "fuse_rename_in:"
  387. " oldname=%s;"
  388. " newdir=%zu;"
  389. " newname=%s;"
  390. "\n"
  391. ,
  392. oldname,
  393. arg->newdir,
  394. newname);
  395. }
  396. static
  397. void
  398. debug_fuse_link_in(const void *arg_)
  399. {
  400. const char *name;
  401. const struct fuse_link_in *arg = arg_;
  402. name = PARAM(arg);
  403. fprintf(g_OUTPUT,
  404. "fuse_link_in:"
  405. " oldnodeid=%zu;"
  406. " name=%s;"
  407. "\n"
  408. ,
  409. arg->oldnodeid,
  410. name);
  411. }
  412. static
  413. void
  414. debug_fuse_create_in(const void *arg_)
  415. {
  416. const char *name;
  417. const struct fuse_create_in *arg = arg_;
  418. name = PARAM(arg);
  419. fprintf(g_OUTPUT,
  420. "fuse_create_in:"
  421. " mode=%o;"
  422. " umask=%o;"
  423. " name=%s;"
  424. " flags=0x%X (",
  425. arg->mode,
  426. arg->umask,
  427. name,
  428. arg->flags);
  429. debug_open_flags(arg->flags);
  430. fprintf(g_OUTPUT,");\n");
  431. }
  432. static
  433. void
  434. debug_fuse_open_in(const void *arg_)
  435. {
  436. const struct fuse_open_in *arg = arg_;
  437. fprintf(g_OUTPUT,
  438. "fuse_open_in:"
  439. " flags=0x%08X (",
  440. arg->flags);
  441. debug_open_flags(arg->flags);
  442. fprintf(g_OUTPUT,");\n");
  443. }
  444. static
  445. void
  446. debug_fuse_read_in(const void *arg_)
  447. {
  448. const struct fuse_read_in *arg = arg_;
  449. fprintf(g_OUTPUT,
  450. "fuse_read_in:"
  451. " fh=0x%"PRIx64";"
  452. " offset=%zu;"
  453. " size=%u;"
  454. " read_flags=%X;"
  455. " lock_owner=0x%"PRIx64";"
  456. " flags=0x%X ("
  457. ,
  458. arg->fh,
  459. arg->offset,
  460. arg->size,
  461. arg->read_flags,
  462. arg->lock_owner,
  463. arg->flags);
  464. debug_open_flags(arg->flags);
  465. fprintf(g_OUTPUT,");\n");
  466. }
  467. static
  468. void
  469. debug_fuse_write_in(const void *arg_)
  470. {
  471. const struct fuse_write_in *arg = arg_;
  472. fprintf(g_OUTPUT,
  473. "fuse_write_in:"
  474. " fh=0x%"PRIx64";"
  475. " offset=%zu;"
  476. " size=%u;"
  477. " lock_owner=0x%"PRIx64";"
  478. " flags=0x%X ("
  479. ,
  480. arg->fh,
  481. arg->offset,
  482. arg->size,
  483. arg->lock_owner,
  484. arg->flags);
  485. debug_open_flags(arg->flags);
  486. fprintf(g_OUTPUT,
  487. "); write_flags=0x%X (",
  488. arg->write_flags);
  489. for(int i = 0; i < (sizeof(arg->write_flags) * 8); i++)
  490. {
  491. const char *str;
  492. if(!(arg->write_flags & (1 << i)))
  493. continue;
  494. str = fuse_write_flag_to_str(i);
  495. if(str == NULL)
  496. continue;
  497. fprintf(g_OUTPUT,"%s,",str);
  498. }
  499. fprintf(g_OUTPUT,");\n");
  500. }
  501. static
  502. void
  503. debug_fuse_flush_in(const void *arg_)
  504. {
  505. const struct fuse_flush_in *arg = arg_;
  506. fprintf(g_OUTPUT,
  507. "fuse_flush_in:"
  508. " fh=0x%"PRIx64";"
  509. " lock_owner=0x%"PRIx64";"
  510. "\n"
  511. ,
  512. arg->fh,
  513. arg->lock_owner);
  514. }
  515. static
  516. void
  517. debug_fuse_release_in(const void *arg_)
  518. {
  519. const struct fuse_release_in *arg = arg_;
  520. fprintf(g_OUTPUT,
  521. "fuse_release_in:"
  522. " fh=0x%"PRIx64";"
  523. " release_flags=0x%X;"
  524. " lock_owner=0x%"PRIx64";"
  525. " flags=0x%X ("
  526. ,
  527. arg->fh,
  528. arg->release_flags,
  529. arg->lock_owner,
  530. arg->flags);
  531. debug_open_flags(arg->flags);
  532. fprintf(g_OUTPUT,");\n");
  533. }
  534. static
  535. void
  536. debug_fuse_fsync_in(const void *arg_)
  537. {
  538. const struct fuse_fsync_in *arg = arg_;
  539. fprintf(g_OUTPUT,
  540. "fuse_fsync_in:"
  541. " fh=0x%"PRIx64";"
  542. " fsync_flags=0x%X;"
  543. "\n"
  544. ,
  545. arg->fh,
  546. arg->fsync_flags);
  547. }
  548. static
  549. void
  550. debug_fuse_setxattr_in(const void *arg_)
  551. {
  552. const char *name;
  553. const char *value;
  554. const struct fuse_setxattr_in *arg = arg_;
  555. name = PARAM(arg);
  556. value = (name + strlen(name) + 1);
  557. fprintf(g_OUTPUT,
  558. "fuse_setxattr_in:"
  559. " size=%u;"
  560. " flags=0x%X;"
  561. " name=%s;"
  562. " value=%s;"
  563. "\n"
  564. ,
  565. arg->size,
  566. arg->flags,
  567. name,
  568. value);
  569. }
  570. static
  571. void
  572. debug_fuse_getxattr_in(const void *arg_)
  573. {
  574. const char *name;
  575. const struct fuse_getxattr_in *arg = arg_;
  576. name = PARAM(arg);
  577. fprintf(g_OUTPUT,
  578. "fuse_getxattr_in:"
  579. " size=%u;"
  580. " name=%s;"
  581. "\n"
  582. ,
  583. arg->size,
  584. name);
  585. }
  586. static
  587. void
  588. debug_fuse_listxattr(const void *arg_)
  589. {
  590. const struct fuse_getxattr_in *arg = arg_;
  591. fprintf(g_OUTPUT,
  592. "fuse_listxattr:"
  593. " size=%u;"
  594. "\n"
  595. ,
  596. arg->size);
  597. }
  598. static
  599. void
  600. debug_fuse_removexattr(const void *arg_)
  601. {
  602. const char *name = arg_;
  603. fprintf(g_OUTPUT,
  604. "fuse_removexattr:"
  605. " name=%s;"
  606. "\n"
  607. ,
  608. name);
  609. }
  610. static
  611. void
  612. debug_fuse_fallocate_in(const void *arg_)
  613. {
  614. const struct fuse_fallocate_in *arg = arg_;
  615. fprintf(g_OUTPUT,
  616. "fuse_fallocate_in:"
  617. " fh=0x%"PRIx64";"
  618. " offset=%zu;"
  619. " length=%zu;"
  620. " mode=%o;"
  621. "\n"
  622. ,
  623. arg->fh,
  624. arg->offset,
  625. arg->length,
  626. arg->mode);
  627. }
  628. void
  629. debug_fuse_init_in(const struct fuse_init_in *arg_)
  630. {
  631. uint64_t flags;
  632. flags = (((uint64_t)arg_->flags) | ((uint64_t)arg_->flags2) << 32);
  633. fprintf(g_OUTPUT,
  634. "FUSE_INIT_IN: "
  635. " major=%u;"
  636. " minor=%u;"
  637. " max_readahead=%u;"
  638. " flags=0x%016lx (",
  639. arg_->major,
  640. arg_->minor,
  641. arg_->max_readahead,
  642. flags);
  643. for(uint64_t i = 0; i < (sizeof(flags)*8); i++)
  644. {
  645. const char *str;
  646. if(!(flags & (1ULL << i)))
  647. continue;
  648. str = fuse_flag_to_str(i);
  649. if(str == NULL)
  650. continue;
  651. fprintf(g_OUTPUT,"%s, ",str);
  652. }
  653. fprintf(g_OUTPUT,")\n");
  654. }
  655. void
  656. debug_fuse_init_out(const uint64_t unique_,
  657. const struct fuse_init_out *arg_,
  658. const uint64_t argsize_)
  659. {
  660. uint64_t flags;
  661. const struct fuse_init_out *arg = arg_;
  662. flags = (((uint64_t)arg->flags) | ((uint64_t)arg->flags2) << 32);
  663. fprintf(g_OUTPUT,
  664. /* "unique=0x%016"PRIx64";" */
  665. /* " opcode=RESPONSE;" */
  666. /* " error=0 (Success);" */
  667. /* " len=%"PRIu64"; || " */
  668. "FUSE_INIT_OUT:"
  669. " major=%u;"
  670. " minor=%u;"
  671. " max_readahead=%u;"
  672. " flags=0x%016lx ("
  673. ,
  674. /* unique_, */
  675. /* sizeof(struct fuse_out_header) + argsize_, */
  676. arg->major,
  677. arg->minor,
  678. arg->max_readahead,
  679. flags);
  680. for(uint64_t i = 0; i < (sizeof(flags)*8); i++)
  681. {
  682. const char *str;
  683. if(!(flags & (1ULL << i)))
  684. continue;
  685. str = fuse_flag_to_str(i);
  686. if(str == NULL)
  687. continue;
  688. fprintf(g_OUTPUT,"%s, ",str);
  689. }
  690. fprintf(g_OUTPUT,
  691. "); max_background=%u;"
  692. " congestion_threshold=%u;"
  693. " max_write=%u;"
  694. " time_gran=%u;"
  695. " max_pages=%u;"
  696. " map_alignment=%u;"
  697. "\n",
  698. arg->max_background,
  699. arg->congestion_threshold,
  700. arg->max_write,
  701. arg->time_gran,
  702. arg->max_pages,
  703. arg->map_alignment);
  704. }
  705. static
  706. void
  707. debug_fuse_attr(const struct fuse_attr *attr_)
  708. {
  709. fprintf(g_OUTPUT,
  710. "attr:"
  711. " ino=0x%016"PRIx64";"
  712. " size=%"PRIu64";"
  713. " blocks=%"PRIu64";"
  714. " atime=%"PRIu64";"
  715. " atimensec=%u;"
  716. " mtime=%"PRIu64";"
  717. " mtimensec=%u;"
  718. " ctime=%"PRIu64";"
  719. " ctimesec=%u;"
  720. " mode=%o;"
  721. " nlink=%u;"
  722. " uid=%u;"
  723. " gid=%u;"
  724. " rdev=%u;"
  725. " blksize=%u;"
  726. ,
  727. attr_->ino,
  728. attr_->size,
  729. attr_->blocks,
  730. attr_->atime,
  731. attr_->atimensec,
  732. attr_->mtime,
  733. attr_->mtimensec,
  734. attr_->ctime,
  735. attr_->ctimensec,
  736. attr_->mode,
  737. attr_->nlink,
  738. attr_->uid,
  739. attr_->gid,
  740. attr_->rdev,
  741. attr_->blksize);
  742. }
  743. static
  744. void
  745. debug_fuse_entry(const struct fuse_entry_out *entry_)
  746. {
  747. fprintf(g_OUTPUT,
  748. " fuse_entry_out:"
  749. " nodeid=0x%016"PRIx64";"
  750. " generation=0x%016"PRIx64";"
  751. " entry_valid=%"PRIu64";"
  752. " entry_valid_nsec=%u;"
  753. " attr_valid=%"PRIu64";"
  754. " attr_valid_nsec=%u;"
  755. " ",
  756. entry_->nodeid,
  757. entry_->generation,
  758. entry_->entry_valid,
  759. entry_->entry_valid_nsec,
  760. entry_->attr_valid,
  761. entry_->attr_valid_nsec);
  762. debug_fuse_attr(&entry_->attr);
  763. }
  764. void
  765. debug_fuse_entry_out(const uint64_t unique_,
  766. const struct fuse_entry_out *arg_,
  767. const uint64_t argsize_)
  768. {
  769. fprintf(g_OUTPUT,
  770. "unique=0x%016"PRIx64";"
  771. " opcode=RESPONSE;"
  772. " error=0 (Success);"
  773. " len=%"PRIu64"; || "
  774. ,
  775. unique_,
  776. sizeof(struct fuse_out_header) + argsize_);
  777. debug_fuse_entry(arg_);
  778. }
  779. void
  780. debug_fuse_attr_out(const uint64_t unique_,
  781. const struct fuse_attr_out *arg_,
  782. const uint64_t argsize_)
  783. {
  784. fprintf(g_OUTPUT,
  785. "unique=0x%016"PRIx64";"
  786. " opcode=RESPONSE;"
  787. " error=0 (Success);"
  788. " len=%"PRIu64"; || "
  789. "fuse_attr_out:"
  790. " attr_valid=%zu;"
  791. " attr_valid_nsec=%u;"
  792. " ino=%zu;"
  793. " size=%zu;"
  794. " blocks=%zu;"
  795. " atime=%zu;"
  796. " atimensec=%u;"
  797. " mtime=%zu;"
  798. " mtimensec=%u;"
  799. " ctime=%zu;"
  800. " ctimensec=%u;"
  801. " mode=%o;"
  802. " nlink=%u;"
  803. " uid=%u;"
  804. " gid=%u;"
  805. " rdev=%u;"
  806. " blksize=%u;"
  807. "\n",
  808. unique_,
  809. sizeof(struct fuse_out_header) + argsize_,
  810. arg_->attr_valid,
  811. arg_->attr_valid_nsec,
  812. arg_->attr.ino,
  813. arg_->attr.size,
  814. arg_->attr.blocks,
  815. arg_->attr.atime,
  816. arg_->attr.atimensec,
  817. arg_->attr.mtime,
  818. arg_->attr.mtimensec,
  819. arg_->attr.ctime,
  820. arg_->attr.ctimensec,
  821. arg_->attr.mode,
  822. arg_->attr.nlink,
  823. arg_->attr.uid,
  824. arg_->attr.gid,
  825. arg_->attr.rdev,
  826. arg_->attr.blksize);
  827. }
  828. static
  829. void
  830. debug_fuse_interrupt_in(const void *arg_)
  831. {
  832. const struct fuse_interrupt_in *arg = arg_;
  833. fprintf(g_OUTPUT,
  834. "fuse_interrupt_in:"
  835. " unique=0x%016"PRIx64";"
  836. "\n"
  837. ,
  838. arg->unique);
  839. }
  840. static
  841. const
  842. char*
  843. opcode_name(enum fuse_opcode op_)
  844. {
  845. static const char *names[] =
  846. {
  847. [FUSE_LOOKUP] = "LOOKUP",
  848. [FUSE_FORGET] = "FORGET",
  849. [FUSE_GETATTR] = "GETATTR",
  850. [FUSE_SETATTR] = "SETATTR",
  851. [FUSE_READLINK] = "READLINK",
  852. [FUSE_SYMLINK] = "SYMLINK",
  853. [FUSE_MKNOD] = "MKNOD",
  854. [FUSE_MKDIR] = "MKDIR",
  855. [FUSE_UNLINK] = "UNLINK",
  856. [FUSE_RMDIR] = "RMDIR",
  857. [FUSE_RENAME] = "RENAME",
  858. [FUSE_LINK] = "LINK",
  859. [FUSE_OPEN] = "OPEN",
  860. [FUSE_READ] = "READ",
  861. [FUSE_WRITE] = "WRITE",
  862. [FUSE_STATFS] = "STATFS",
  863. [FUSE_RELEASE] = "RELEASE",
  864. [FUSE_FSYNC] = "FSYNC",
  865. [FUSE_SETXATTR] = "SETXATTR",
  866. [FUSE_GETXATTR] = "GETXATTR",
  867. [FUSE_LISTXATTR] = "LISTXATTR",
  868. [FUSE_REMOVEXATTR] = "REMOVEXATTR",
  869. [FUSE_FLUSH] = "FLUSH",
  870. [FUSE_INIT] = "INIT",
  871. [FUSE_OPENDIR] = "OPENDIR",
  872. [FUSE_READDIR] = "READDIR",
  873. [FUSE_RELEASEDIR] = "RELEASEDIR",
  874. [FUSE_FSYNCDIR] = "FSYNCDIR",
  875. [FUSE_GETLK] = "GETLK",
  876. [FUSE_SETLK] = "SETLK",
  877. [FUSE_SETLKW] = "SETLKW",
  878. [FUSE_ACCESS] = "ACCESS",
  879. [FUSE_CREATE] = "CREATE",
  880. [FUSE_INTERRUPT] = "INTERRUPT",
  881. [FUSE_BMAP] = "BMAP",
  882. [FUSE_DESTROY] = "DESTROY",
  883. [FUSE_IOCTL] = "IOCTL",
  884. [FUSE_POLL] = "POLL",
  885. [FUSE_NOTIFY_REPLY] = "NOTIFY_REPLY",
  886. [FUSE_BATCH_FORGET] = "BATCH_FORGET",
  887. [FUSE_FALLOCATE] = "FALLOCATE",
  888. [FUSE_READDIRPLUS] = "READDIRPLUS",
  889. [FUSE_RENAME2] = "RENAME2",
  890. [FUSE_LSEEK] = "LSEEK",
  891. [FUSE_COPY_FILE_RANGE] = "COPY_FILE_RANGE",
  892. [FUSE_SETUPMAPPING] = "SETUPMAPPING",
  893. [FUSE_REMOVEMAPPING] = "REMOVEMAPPING"
  894. };
  895. if(op_ >= (sizeof(names) / sizeof(names[0])))
  896. return "::UNKNOWN::";
  897. return names[op_];
  898. }
  899. void
  900. debug_fuse_in_header(const struct fuse_in_header *hdr_)
  901. {
  902. const void *arg = &hdr_[1];
  903. fprintf(stderr,
  904. "unique=0x%016"PRIx64";"
  905. " opcode=%s (%u);"
  906. " nodeid=%zu;"
  907. " uid=%u;"
  908. " gid=%u;"
  909. " pid=%u; || ",
  910. hdr_->unique,
  911. opcode_name(hdr_->opcode),
  912. hdr_->opcode,
  913. hdr_->nodeid,
  914. hdr_->uid,
  915. hdr_->gid,
  916. hdr_->pid);
  917. switch(hdr_->opcode)
  918. {
  919. case FUSE_LOOKUP:
  920. debug_fuse_lookup(arg);
  921. break;
  922. case FUSE_INIT:
  923. debug_fuse_init_in(arg);
  924. break;
  925. case FUSE_GETATTR:
  926. debug_fuse_getattr_in(arg);
  927. break;
  928. case FUSE_SETATTR:
  929. debug_fuse_setattr_in(arg);
  930. break;
  931. case FUSE_ACCESS:
  932. debug_fuse_access_in(arg);
  933. break;
  934. case FUSE_MKNOD:
  935. debug_fuse_mknod_in(arg);
  936. break;
  937. case FUSE_MKDIR:
  938. debug_fuse_mkdir_in(arg);
  939. break;
  940. case FUSE_UNLINK:
  941. debug_fuse_unlink(arg);
  942. break;
  943. case FUSE_RMDIR:
  944. debug_fuse_rmdir(arg);
  945. break;
  946. case FUSE_SYMLINK:
  947. debug_fuse_symlink(arg);
  948. break;
  949. case FUSE_RENAME:
  950. debug_fuse_rename_in(arg);
  951. break;
  952. case FUSE_LINK:
  953. debug_fuse_link_in(arg);
  954. break;
  955. case FUSE_CREATE:
  956. debug_fuse_create_in(arg);
  957. break;
  958. case FUSE_OPEN:
  959. debug_fuse_open_in(arg);
  960. break;
  961. case FUSE_OPENDIR:
  962. debug_fuse_open_in(arg);
  963. break;
  964. case FUSE_READ:
  965. debug_fuse_read_in(arg);
  966. break;
  967. case FUSE_READDIR:
  968. debug_fuse_read_in(arg);
  969. break;
  970. case FUSE_READDIRPLUS:
  971. debug_fuse_read_in(arg);
  972. break;
  973. case FUSE_WRITE:
  974. debug_fuse_write_in(arg);
  975. break;
  976. case FUSE_RELEASE:
  977. debug_fuse_release_in(arg);
  978. break;
  979. case FUSE_RELEASEDIR:
  980. debug_fuse_release_in(arg);
  981. break;
  982. case FUSE_FSYNCDIR:
  983. debug_fuse_fsync_in(arg);
  984. break;
  985. case FUSE_GETXATTR:
  986. debug_fuse_getxattr_in(arg);
  987. break;
  988. case FUSE_LISTXATTR:
  989. debug_fuse_listxattr(arg);
  990. break;
  991. case FUSE_SETXATTR:
  992. debug_fuse_setxattr_in(arg);
  993. break;
  994. case FUSE_REMOVEXATTR:
  995. debug_fuse_removexattr(arg);
  996. break;
  997. case FUSE_FALLOCATE:
  998. debug_fuse_fallocate_in(arg);
  999. break;
  1000. case FUSE_FLUSH:
  1001. debug_fuse_flush_in(arg);
  1002. break;
  1003. case FUSE_INTERRUPT:
  1004. debug_fuse_interrupt_in(arg);
  1005. break;
  1006. default:
  1007. fprintf(g_OUTPUT,"FIXME\n");
  1008. break;
  1009. }
  1010. }
  1011. void
  1012. debug_fuse_out_header(const struct fuse_out_header *hdr_)
  1013. {
  1014. fprintf(g_OUTPUT,
  1015. "unique=0x%016"PRIx64";"
  1016. " opcode=RESPONSE;"
  1017. " error=%d (%s);"
  1018. " len=%"PRIu64";"
  1019. ,
  1020. hdr_->unique,
  1021. hdr_->error,
  1022. strerror(-hdr_->error),
  1023. sizeof(struct fuse_out_header));
  1024. }
  1025. void
  1026. debug_fuse_entry_open_out(const uint64_t unique_,
  1027. const struct fuse_entry_out *entry_,
  1028. const struct fuse_open_out *open_)
  1029. {
  1030. fprintf(g_OUTPUT,
  1031. "unique=0x%016"PRIx64";"
  1032. " opcode=RESPONSE;"
  1033. " error=0 (Success);"
  1034. " len=%"PRIu64"; || "
  1035. ,
  1036. unique_,
  1037. sizeof(struct fuse_entry_out) + sizeof(struct fuse_open_out));
  1038. debug_fuse_entry(entry_);
  1039. }
  1040. void
  1041. debug_fuse_readlink(const uint64_t unique_,
  1042. const char *linkname_)
  1043. {
  1044. fprintf(g_OUTPUT,
  1045. "unique=0x%016"PRIx64";"
  1046. " opcode=RESPONSE;"
  1047. " error=0 (Success);"
  1048. " len=%"PRIu64"; || "
  1049. "readlink: linkname=%s"
  1050. "\n"
  1051. ,
  1052. unique_,
  1053. (sizeof(struct fuse_out_header) + strlen(linkname_)),
  1054. linkname_);
  1055. }
  1056. void
  1057. debug_fuse_write_out(const uint64_t unique_,
  1058. const struct fuse_write_out *arg_)
  1059. {
  1060. fprintf(g_OUTPUT,
  1061. "unique=0x%016"PRIx64";"
  1062. " opcode=RESPONSE;"
  1063. " error=0 (Success);"
  1064. " len=%"PRIu64"; || "
  1065. " fuse_write_out:"
  1066. " size=%u"
  1067. "\n"
  1068. ,
  1069. unique_,
  1070. sizeof(struct fuse_write_out),
  1071. arg_->size);
  1072. }
  1073. void
  1074. debug_fuse_statfs_out(const uint64_t unique_,
  1075. const struct fuse_statfs_out *arg_)
  1076. {
  1077. fprintf(g_OUTPUT,
  1078. "unique=0x%016"PRIx64";"
  1079. " opcode=RESPONSE;"
  1080. " error=0 (Success);"
  1081. " len=%"PRIu64"; || "
  1082. " fuse_statfs_out:"
  1083. " blocks=%"PRIu64";"
  1084. " bfree=%"PRIu64";"
  1085. " bavail=%"PRIu64";"
  1086. " files=%"PRIu64";"
  1087. " ffree=%"PRIu64";"
  1088. " bsize=%u;"
  1089. " namelen=%u;"
  1090. " frsize=%u;"
  1091. "\n"
  1092. ,
  1093. unique_,
  1094. sizeof(struct fuse_statfs_out),
  1095. arg_->st.blocks,
  1096. arg_->st.bfree,
  1097. arg_->st.bavail,
  1098. arg_->st.files,
  1099. arg_->st.ffree,
  1100. arg_->st.bsize,
  1101. arg_->st.namelen,
  1102. arg_->st.frsize);
  1103. }
  1104. void
  1105. debug_fuse_getxattr_out(const uint64_t unique_,
  1106. const struct fuse_getxattr_out *arg_)
  1107. {
  1108. fprintf(g_OUTPUT,
  1109. "unique=0x%016"PRIx64";"
  1110. " opcode=RESPONSE;"
  1111. " error=0 (Success);"
  1112. " len=%"PRIu64"; || "
  1113. " fuse_getxattr_out:"
  1114. " size=%u;"
  1115. "\n"
  1116. ,
  1117. unique_,
  1118. sizeof(struct fuse_out_header) + sizeof(struct fuse_getxattr_out),
  1119. arg_->size);
  1120. }
  1121. void
  1122. debug_fuse_lk_out(const uint64_t unique_,
  1123. const struct fuse_lk_out *arg_)
  1124. {
  1125. fprintf(g_OUTPUT,
  1126. "unique=0x%016"PRIx64";"
  1127. " opcode=RESPONSE;"
  1128. " error=0 (Success);"
  1129. " len=%"PRIu64"; || "
  1130. " fuse_file_lock:"
  1131. " start=%"PRIu64";"
  1132. " end=%"PRIu64";"
  1133. " type=%u;"
  1134. " pid=%u;"
  1135. "\n"
  1136. ,
  1137. unique_,
  1138. sizeof(struct fuse_out_header) + sizeof(struct fuse_lk_out),
  1139. arg_->lk.start,
  1140. arg_->lk.end,
  1141. arg_->lk.type,
  1142. arg_->lk.pid);
  1143. }
  1144. void
  1145. debug_fuse_bmap_out(const uint64_t unique_,
  1146. const struct fuse_bmap_out *arg_)
  1147. {
  1148. fprintf(g_OUTPUT,
  1149. "unique=0x%016"PRIx64";"
  1150. " opcode=RESPONSE;"
  1151. " error=0 (Success);"
  1152. " len=%"PRIu64"; || "
  1153. " fuse_bmap_out:"
  1154. " block=%"PRIu64";"
  1155. "\n"
  1156. ,
  1157. unique_,
  1158. sizeof(struct fuse_out_header) + sizeof(struct fuse_bmap_out),
  1159. arg_->block);
  1160. }