main.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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_FOR_WRITE] = "RW",
  34. [NETFS_DIO_READ] = "DR",
  35. [NETFS_WRITEBACK] = "WB",
  36. [NETFS_WRITETHROUGH] = "WT",
  37. [NETFS_UNBUFFERED_WRITE] = "UW",
  38. [NETFS_DIO_WRITE] = "DW",
  39. [NETFS_PGPRIV2_COPY_TO_CACHE] = "2C",
  40. };
  41. /*
  42. * Generate a list of I/O requests in /proc/fs/netfs/requests
  43. */
  44. static int netfs_requests_seq_show(struct seq_file *m, void *v)
  45. {
  46. struct netfs_io_request *rreq;
  47. if (v == &netfs_io_requests) {
  48. seq_puts(m,
  49. "REQUEST OR REF FL ERR OPS COVERAGE\n"
  50. "======== == === == ==== === =========\n"
  51. );
  52. return 0;
  53. }
  54. rreq = list_entry(v, struct netfs_io_request, proc_link);
  55. seq_printf(m,
  56. "%08x %s %3d %2lx %4ld %3d @%04llx %llx/%llx",
  57. rreq->debug_id,
  58. netfs_origins[rreq->origin],
  59. refcount_read(&rreq->ref),
  60. rreq->flags,
  61. rreq->error,
  62. atomic_read(&rreq->nr_outstanding),
  63. rreq->start, rreq->submitted, rreq->len);
  64. seq_putc(m, '\n');
  65. return 0;
  66. }
  67. static void *netfs_requests_seq_start(struct seq_file *m, loff_t *_pos)
  68. __acquires(rcu)
  69. {
  70. rcu_read_lock();
  71. return seq_list_start_head(&netfs_io_requests, *_pos);
  72. }
  73. static void *netfs_requests_seq_next(struct seq_file *m, void *v, loff_t *_pos)
  74. {
  75. return seq_list_next(v, &netfs_io_requests, _pos);
  76. }
  77. static void netfs_requests_seq_stop(struct seq_file *m, void *v)
  78. __releases(rcu)
  79. {
  80. rcu_read_unlock();
  81. }
  82. static const struct seq_operations netfs_requests_seq_ops = {
  83. .start = netfs_requests_seq_start,
  84. .next = netfs_requests_seq_next,
  85. .stop = netfs_requests_seq_stop,
  86. .show = netfs_requests_seq_show,
  87. };
  88. #endif /* CONFIG_PROC_FS */
  89. static int __init netfs_init(void)
  90. {
  91. int ret = -ENOMEM;
  92. netfs_request_slab = kmem_cache_create("netfs_request",
  93. sizeof(struct netfs_io_request), 0,
  94. SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
  95. NULL);
  96. if (!netfs_request_slab)
  97. goto error_req;
  98. if (mempool_init_slab_pool(&netfs_request_pool, 100, netfs_request_slab) < 0)
  99. goto error_reqpool;
  100. netfs_subrequest_slab = kmem_cache_create("netfs_subrequest",
  101. sizeof(struct netfs_io_subrequest), 0,
  102. SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
  103. NULL);
  104. if (!netfs_subrequest_slab)
  105. goto error_subreq;
  106. if (mempool_init_slab_pool(&netfs_subrequest_pool, 100, netfs_subrequest_slab) < 0)
  107. goto error_subreqpool;
  108. #ifdef CONFIG_PROC_FS
  109. if (!proc_mkdir("fs/netfs", NULL))
  110. goto error_proc;
  111. if (!proc_create_seq("fs/netfs/requests", S_IFREG | 0444, NULL,
  112. &netfs_requests_seq_ops))
  113. goto error_procfile;
  114. #endif
  115. #ifdef CONFIG_FSCACHE_STATS
  116. if (!proc_create_single("fs/netfs/stats", S_IFREG | 0444, NULL,
  117. netfs_stats_show))
  118. goto error_procfile;
  119. #endif
  120. ret = fscache_init();
  121. if (ret < 0)
  122. goto error_fscache;
  123. return 0;
  124. error_fscache:
  125. #ifdef CONFIG_PROC_FS
  126. error_procfile:
  127. remove_proc_subtree("fs/netfs", NULL);
  128. error_proc:
  129. #endif
  130. mempool_exit(&netfs_subrequest_pool);
  131. error_subreqpool:
  132. kmem_cache_destroy(netfs_subrequest_slab);
  133. error_subreq:
  134. mempool_exit(&netfs_request_pool);
  135. error_reqpool:
  136. kmem_cache_destroy(netfs_request_slab);
  137. error_req:
  138. return ret;
  139. }
  140. fs_initcall(netfs_init);
  141. static void __exit netfs_exit(void)
  142. {
  143. fscache_exit();
  144. remove_proc_subtree("fs/netfs", NULL);
  145. mempool_exit(&netfs_subrequest_pool);
  146. kmem_cache_destroy(netfs_subrequest_slab);
  147. mempool_exit(&netfs_request_pool);
  148. kmem_cache_destroy(netfs_request_slab);
  149. }
  150. module_exit(netfs_exit);