main.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Miscellaneous bits for the netfs support library.
  3. *
  4. * Copyright (C) 2022 Red Hat, Inc. All Rights Reserved.
  5. * Written by David Howells (dhowells@redhat.com)
  6. */
  7. #include <linux/module.h>
  8. #include <linux/export.h>
  9. #include <linux/mempool.h>
  10. #include <linux/proc_fs.h>
  11. #include <linux/seq_file.h>
  12. #include "internal.h"
  13. #define CREATE_TRACE_POINTS
  14. #include <trace/events/netfs.h>
  15. MODULE_DESCRIPTION("Network fs support");
  16. MODULE_AUTHOR("Red Hat, Inc.");
  17. MODULE_LICENSE("GPL");
  18. EXPORT_TRACEPOINT_SYMBOL(netfs_sreq);
  19. unsigned netfs_debug;
  20. module_param_named(debug, netfs_debug, uint, S_IWUSR | S_IRUGO);
  21. MODULE_PARM_DESC(netfs_debug, "Netfs support debugging mask");
  22. static struct kmem_cache *netfs_request_slab;
  23. static struct kmem_cache *netfs_subrequest_slab;
  24. mempool_t netfs_request_pool;
  25. mempool_t netfs_subrequest_pool;
  26. #ifdef CONFIG_PROC_FS
  27. LIST_HEAD(netfs_io_requests);
  28. DEFINE_SPINLOCK(netfs_proc_lock);
  29. static const char *netfs_origins[nr__netfs_io_origin] = {
  30. [NETFS_READAHEAD] = "RA",
  31. [NETFS_READPAGE] = "RP",
  32. [NETFS_READ_GAPS] = "RG",
  33. [NETFS_READ_SINGLE] = "R1",
  34. [NETFS_READ_FOR_WRITE] = "RW",
  35. [NETFS_UNBUFFERED_READ] = "UR",
  36. [NETFS_DIO_READ] = "DR",
  37. [NETFS_WRITEBACK] = "WB",
  38. [NETFS_WRITEBACK_SINGLE] = "W1",
  39. [NETFS_WRITETHROUGH] = "WT",
  40. [NETFS_UNBUFFERED_WRITE] = "UW",
  41. [NETFS_DIO_WRITE] = "DW",
  42. [NETFS_PGPRIV2_COPY_TO_CACHE] = "2C",
  43. };
  44. /*
  45. * Generate a list of I/O requests in /proc/fs/netfs/requests
  46. */
  47. static int netfs_requests_seq_show(struct seq_file *m, void *v)
  48. {
  49. struct netfs_io_request *rreq;
  50. if (v == &netfs_io_requests) {
  51. seq_puts(m,
  52. "REQUEST OR REF FLAG ERR OPS COVERAGE\n"
  53. "======== == === ==== ==== === =========\n"
  54. );
  55. return 0;
  56. }
  57. rreq = list_entry(v, struct netfs_io_request, proc_link);
  58. seq_printf(m,
  59. "%08x %s %3d %4lx %4ld %3d @%04llx %llx/%llx",
  60. rreq->debug_id,
  61. netfs_origins[rreq->origin],
  62. refcount_read(&rreq->ref),
  63. rreq->flags,
  64. rreq->error,
  65. 0,
  66. rreq->start, rreq->submitted, rreq->len);
  67. seq_putc(m, '\n');
  68. return 0;
  69. }
  70. static void *netfs_requests_seq_start(struct seq_file *m, loff_t *_pos)
  71. __acquires(rcu)
  72. {
  73. rcu_read_lock();
  74. return seq_list_start_head(&netfs_io_requests, *_pos);
  75. }
  76. static void *netfs_requests_seq_next(struct seq_file *m, void *v, loff_t *_pos)
  77. {
  78. return seq_list_next(v, &netfs_io_requests, _pos);
  79. }
  80. static void netfs_requests_seq_stop(struct seq_file *m, void *v)
  81. __releases(rcu)
  82. {
  83. rcu_read_unlock();
  84. }
  85. static const struct seq_operations netfs_requests_seq_ops = {
  86. .start = netfs_requests_seq_start,
  87. .next = netfs_requests_seq_next,
  88. .stop = netfs_requests_seq_stop,
  89. .show = netfs_requests_seq_show,
  90. };
  91. #endif /* CONFIG_PROC_FS */
  92. static int __init netfs_init(void)
  93. {
  94. int ret = -ENOMEM;
  95. netfs_request_slab = kmem_cache_create("netfs_request",
  96. sizeof(struct netfs_io_request), 0,
  97. SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
  98. NULL);
  99. if (!netfs_request_slab)
  100. goto error_req;
  101. if (mempool_init_slab_pool(&netfs_request_pool, 100, netfs_request_slab) < 0)
  102. goto error_reqpool;
  103. netfs_subrequest_slab = kmem_cache_create("netfs_subrequest",
  104. sizeof(struct netfs_io_subrequest) + 16, 0,
  105. SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
  106. NULL);
  107. if (!netfs_subrequest_slab)
  108. goto error_subreq;
  109. if (mempool_init_slab_pool(&netfs_subrequest_pool, 100, netfs_subrequest_slab) < 0)
  110. goto error_subreqpool;
  111. #ifdef CONFIG_PROC_FS
  112. if (!proc_mkdir("fs/netfs", NULL))
  113. goto error_proc;
  114. if (!proc_create_seq("fs/netfs/requests", S_IFREG | 0444, NULL,
  115. &netfs_requests_seq_ops))
  116. goto error_procfile;
  117. #endif
  118. #ifdef CONFIG_FSCACHE_STATS
  119. if (!proc_create_single("fs/netfs/stats", S_IFREG | 0444, NULL,
  120. netfs_stats_show))
  121. goto error_procfile;
  122. #endif
  123. ret = fscache_init();
  124. if (ret < 0)
  125. goto error_fscache;
  126. return 0;
  127. error_fscache:
  128. #ifdef CONFIG_PROC_FS
  129. error_procfile:
  130. remove_proc_subtree("fs/netfs", NULL);
  131. error_proc:
  132. #endif
  133. mempool_exit(&netfs_subrequest_pool);
  134. error_subreqpool:
  135. kmem_cache_destroy(netfs_subrequest_slab);
  136. error_subreq:
  137. mempool_exit(&netfs_request_pool);
  138. error_reqpool:
  139. kmem_cache_destroy(netfs_request_slab);
  140. error_req:
  141. return ret;
  142. }
  143. fs_initcall(netfs_init);
  144. static void __exit netfs_exit(void)
  145. {
  146. fscache_exit();
  147. remove_proc_subtree("fs/netfs", NULL);
  148. mempool_exit(&netfs_subrequest_pool);
  149. kmem_cache_destroy(netfs_subrequest_slab);
  150. mempool_exit(&netfs_request_pool);
  151. kmem_cache_destroy(netfs_request_slab);
  152. }
  153. module_exit(netfs_exit);