452-block-add-support-for-notifications.patch 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. From patchwork Tue Jul 30 19:26:42 2024
  2. Content-Type: text/plain; charset="utf-8"
  3. MIME-Version: 1.0
  4. Content-Transfer-Encoding: 7bit
  5. X-Patchwork-Submitter: Daniel Golle <[email protected]>
  6. X-Patchwork-Id: 13747817
  7. Date: Tue, 30 Jul 2024 20:26:42 +0100
  8. From: Daniel Golle <[email protected]>
  9. To: Rob Herring <[email protected]>, Krzysztof Kozlowski <[email protected]>,
  10. Conor Dooley <[email protected]>, Jens Axboe <[email protected]>,
  11. Daniel Golle <[email protected]>, Christian Brauner <[email protected]>,
  12. Al Viro <[email protected]>, Li Lingfeng <[email protected]>,
  13. Ming Lei <[email protected]>, Christian Heusel <[email protected]>,
  14. =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= <[email protected]>,
  15. Felix Fietkau <[email protected]>, John Crispin <[email protected]>,
  16. Chad Monroe <[email protected]>, Yangyu Chen <[email protected]>,
  17. Tianling Shen <[email protected]>, Chuanhong Guo <[email protected]>,
  18. Chen Minqiang <[email protected]>, [email protected],
  19. [email protected], [email protected]
  20. Subject: [PATCH v5 3/4] block: add support for notifications
  21. Message-ID:
  22. <ca0022886e8f211a323a716653a1396a3bc91653.1722365899.git.daniel@makrotopia.org>
  23. References: <[email protected]>
  24. Precedence: bulk
  25. X-Mailing-List: [email protected]
  26. List-Id: <linux-block.vger.kernel.org>
  27. List-Subscribe: <mailto:[email protected]>
  28. List-Unsubscribe: <mailto:[email protected]>
  29. MIME-Version: 1.0
  30. Content-Disposition: inline
  31. In-Reply-To: <[email protected]>
  32. Add notifier block to notify other subsystems about the addition or
  33. removal of block devices.
  34. Signed-off-by: Daniel Golle <[email protected]>
  35. ---
  36. block/Kconfig | 6 +++
  37. block/Makefile | 1 +
  38. block/blk-notify.c | 87 ++++++++++++++++++++++++++++++++++++++++++
  39. include/linux/blkdev.h | 11 ++++++
  40. 4 files changed, 105 insertions(+)
  41. create mode 100644 block/blk-notify.c
  42. --- a/block/Kconfig
  43. +++ b/block/Kconfig
  44. @@ -208,6 +208,12 @@ config BLK_INLINE_ENCRYPTION_FALLBACK
  45. by falling back to the kernel crypto API when inline
  46. encryption hardware is not present.
  47. +config BLOCK_NOTIFIERS
  48. + bool "Enable support for notifications in block layer"
  49. + help
  50. + Enable this option to provide notifiers for other subsystems
  51. + upon addition or removal of block devices.
  52. +
  53. source "block/partitions/Kconfig"
  54. config BLK_MQ_PCI
  55. --- a/block/Makefile
  56. +++ b/block/Makefile
  57. @@ -40,3 +40,4 @@ obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += b
  58. blk-crypto-sysfs.o
  59. obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) += blk-crypto-fallback.o
  60. obj-$(CONFIG_BLOCK_HOLDER_DEPRECATED) += holder.o
  61. +obj-$(CONFIG_BLOCK_NOTIFIERS) += blk-notify.o
  62. --- /dev/null
  63. +++ b/block/blk-notify.c
  64. @@ -0,0 +1,87 @@
  65. +// SPDX-License-Identifier: GPL-2.0-or-later
  66. +/*
  67. + * Notifiers for addition and removal of block devices
  68. + *
  69. + * Copyright (c) 2024 Daniel Golle <[email protected]>
  70. + */
  71. +
  72. +#include <linux/list.h>
  73. +#include <linux/mutex.h>
  74. +#include <linux/notifier.h>
  75. +
  76. +#include "blk.h"
  77. +
  78. +struct blk_device_list {
  79. + struct device *dev;
  80. + struct list_head list;
  81. +};
  82. +
  83. +static RAW_NOTIFIER_HEAD(blk_notifier_list);
  84. +static DEFINE_MUTEX(blk_notifier_lock);
  85. +static LIST_HEAD(blk_devices);
  86. +
  87. +void blk_register_notify(struct notifier_block *nb)
  88. +{
  89. + struct blk_device_list *existing_blkdev;
  90. +
  91. + mutex_lock(&blk_notifier_lock);
  92. + raw_notifier_chain_register(&blk_notifier_list, nb);
  93. +
  94. + list_for_each_entry(existing_blkdev, &blk_devices, list)
  95. + nb->notifier_call(nb, BLK_DEVICE_ADD, existing_blkdev->dev);
  96. +
  97. + mutex_unlock(&blk_notifier_lock);
  98. +}
  99. +EXPORT_SYMBOL_GPL(blk_register_notify);
  100. +
  101. +void blk_unregister_notify(struct notifier_block *nb)
  102. +{
  103. + mutex_lock(&blk_notifier_lock);
  104. + raw_notifier_chain_unregister(&blk_notifier_list, nb);
  105. + mutex_unlock(&blk_notifier_lock);
  106. +}
  107. +EXPORT_SYMBOL_GPL(blk_unregister_notify);
  108. +
  109. +static int blk_call_notifier_add(struct device *dev)
  110. +{
  111. + struct blk_device_list *new_blkdev;
  112. +
  113. + new_blkdev = kmalloc(sizeof(*new_blkdev), GFP_KERNEL);
  114. + if (!new_blkdev)
  115. + return -ENOMEM;
  116. +
  117. + new_blkdev->dev = dev;
  118. + mutex_lock(&blk_notifier_lock);
  119. + list_add_tail(&new_blkdev->list, &blk_devices);
  120. + raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_ADD, dev);
  121. + mutex_unlock(&blk_notifier_lock);
  122. + return 0;
  123. +}
  124. +
  125. +static void blk_call_notifier_remove(struct device *dev)
  126. +{
  127. + struct blk_device_list *old_blkdev, *tmp;
  128. +
  129. + mutex_lock(&blk_notifier_lock);
  130. + list_for_each_entry_safe(old_blkdev, tmp, &blk_devices, list) {
  131. + if (old_blkdev->dev != dev)
  132. + continue;
  133. +
  134. + list_del(&old_blkdev->list);
  135. + kfree(old_blkdev);
  136. + }
  137. + raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_REMOVE, dev);
  138. + mutex_unlock(&blk_notifier_lock);
  139. +}
  140. +
  141. +static struct class_interface blk_notifications_bus_interface __refdata = {
  142. + .class = &block_class,
  143. + .add_dev = &blk_call_notifier_add,
  144. + .remove_dev = &blk_call_notifier_remove,
  145. +};
  146. +
  147. +static int __init blk_notifications_init(void)
  148. +{
  149. + return class_interface_register(&blk_notifications_bus_interface);
  150. +}
  151. +device_initcall(blk_notifications_init);
  152. --- a/include/linux/blkdev.h
  153. +++ b/include/linux/blkdev.h
  154. @@ -1567,4 +1567,15 @@ struct io_comp_batch {
  155. #define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
  156. +
  157. +#define BLK_DEVICE_ADD 1
  158. +#define BLK_DEVICE_REMOVE 2
  159. +#if defined(CONFIG_BLOCK_NOTIFIERS)
  160. +void blk_register_notify(struct notifier_block *nb);
  161. +void blk_unregister_notify(struct notifier_block *nb);
  162. +#else
  163. +static inline void blk_register_notify(struct notifier_block *nb) { };
  164. +static inline void blk_unregister_notify(struct notifier_block *nb) { };
  165. +#endif
  166. +
  167. #endif /* _LINUX_BLKDEV_H */