item.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * item.c - library routines for handling generic config items
  4. *
  5. * Based on kobject:
  6. * kobject is Copyright (c) 2002-2003 Patrick Mochel
  7. *
  8. * configfs Copyright (C) 2005 Oracle. All rights reserved.
  9. *
  10. * Please see the file Documentation/filesystems/configfs.rst for
  11. * critical information about using the config_item interface.
  12. */
  13. #include <linux/string.h>
  14. #include <linux/module.h>
  15. #include <linux/stat.h>
  16. #include <linux/slab.h>
  17. #include <linux/configfs.h>
  18. static inline struct config_item *to_item(struct list_head *entry)
  19. {
  20. return container_of(entry, struct config_item, ci_entry);
  21. }
  22. /* Evil kernel */
  23. static void config_item_release(struct kref *kref);
  24. /**
  25. * config_item_init - initialize item.
  26. * @item: item in question.
  27. */
  28. static void config_item_init(struct config_item *item)
  29. {
  30. kref_init(&item->ci_kref);
  31. INIT_LIST_HEAD(&item->ci_entry);
  32. }
  33. /**
  34. * config_item_set_name - Set the name of an item
  35. * @item: item.
  36. * @fmt: The vsnprintf()'s format string.
  37. *
  38. * If strlen(name) >= CONFIGFS_ITEM_NAME_LEN, then use a
  39. * dynamically allocated string that @item->ci_name points to.
  40. * Otherwise, use the static @item->ci_namebuf array.
  41. */
  42. int config_item_set_name(struct config_item *item, const char *fmt, ...)
  43. {
  44. int limit = CONFIGFS_ITEM_NAME_LEN;
  45. int need;
  46. va_list args;
  47. char *name;
  48. /*
  49. * First, try the static array
  50. */
  51. va_start(args, fmt);
  52. need = vsnprintf(item->ci_namebuf, limit, fmt, args);
  53. va_end(args);
  54. if (need < limit)
  55. name = item->ci_namebuf;
  56. else {
  57. va_start(args, fmt);
  58. name = kvasprintf(GFP_KERNEL, fmt, args);
  59. va_end(args);
  60. if (!name)
  61. return -EFAULT;
  62. }
  63. /* Free the old name, if necessary. */
  64. if (item->ci_name && item->ci_name != item->ci_namebuf)
  65. kfree(item->ci_name);
  66. /* Now, set the new name */
  67. item->ci_name = name;
  68. return 0;
  69. }
  70. EXPORT_SYMBOL(config_item_set_name);
  71. void config_item_init_type_name(struct config_item *item,
  72. const char *name,
  73. const struct config_item_type *type)
  74. {
  75. config_item_set_name(item, "%s", name);
  76. item->ci_type = type;
  77. config_item_init(item);
  78. }
  79. EXPORT_SYMBOL(config_item_init_type_name);
  80. void config_group_init_type_name(struct config_group *group, const char *name,
  81. const struct config_item_type *type)
  82. {
  83. config_item_set_name(&group->cg_item, "%s", name);
  84. group->cg_item.ci_type = type;
  85. config_group_init(group);
  86. }
  87. EXPORT_SYMBOL(config_group_init_type_name);
  88. struct config_item *config_item_get(struct config_item *item)
  89. {
  90. if (item)
  91. kref_get(&item->ci_kref);
  92. return item;
  93. }
  94. EXPORT_SYMBOL(config_item_get);
  95. struct config_item *config_item_get_unless_zero(struct config_item *item)
  96. {
  97. if (item && kref_get_unless_zero(&item->ci_kref))
  98. return item;
  99. return NULL;
  100. }
  101. EXPORT_SYMBOL(config_item_get_unless_zero);
  102. static void config_item_cleanup(struct config_item *item)
  103. {
  104. const struct config_item_type *t = item->ci_type;
  105. struct config_group *s = item->ci_group;
  106. struct config_item *parent = item->ci_parent;
  107. pr_debug("config_item %s: cleaning up\n", config_item_name(item));
  108. if (item->ci_name != item->ci_namebuf)
  109. kfree(item->ci_name);
  110. item->ci_name = NULL;
  111. if (t && t->ct_item_ops && t->ct_item_ops->release)
  112. t->ct_item_ops->release(item);
  113. if (s)
  114. config_group_put(s);
  115. if (parent)
  116. config_item_put(parent);
  117. }
  118. static void config_item_release(struct kref *kref)
  119. {
  120. config_item_cleanup(container_of(kref, struct config_item, ci_kref));
  121. }
  122. /**
  123. * config_item_put - decrement refcount for item.
  124. * @item: item.
  125. *
  126. * Decrement the refcount, and if 0, call config_item_cleanup().
  127. */
  128. void config_item_put(struct config_item *item)
  129. {
  130. if (item)
  131. kref_put(&item->ci_kref, config_item_release);
  132. }
  133. EXPORT_SYMBOL(config_item_put);
  134. /**
  135. * config_group_init - initialize a group for use
  136. * @group: config_group
  137. */
  138. void config_group_init(struct config_group *group)
  139. {
  140. config_item_init(&group->cg_item);
  141. INIT_LIST_HEAD(&group->cg_children);
  142. INIT_LIST_HEAD(&group->default_groups);
  143. }
  144. EXPORT_SYMBOL(config_group_init);
  145. /**
  146. * config_group_find_item - search for item in group.
  147. * @group: group we're looking in.
  148. * @name: item's name.
  149. *
  150. * Iterate over @group->cg_list, looking for a matching config_item.
  151. * If matching item is found take a reference and return the item.
  152. * Caller must have locked group via @group->cg_subsys->su_mtx.
  153. */
  154. struct config_item *config_group_find_item(struct config_group *group,
  155. const char *name)
  156. {
  157. struct list_head *entry;
  158. struct config_item *ret = NULL;
  159. list_for_each(entry, &group->cg_children) {
  160. struct config_item *item = to_item(entry);
  161. if (config_item_name(item) &&
  162. !strcmp(config_item_name(item), name)) {
  163. ret = config_item_get(item);
  164. break;
  165. }
  166. }
  167. return ret;
  168. }
  169. EXPORT_SYMBOL(config_group_find_item);