root/fs/configfs/item.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_item
  2. config_item_init
  3. config_item_set_name
  4. config_item_init_type_name
  5. config_group_init_type_name
  6. config_item_get
  7. config_item_get_unless_zero
  8. config_item_cleanup
  9. config_item_release
  10. config_item_put
  11. config_group_init
  12. config_group_find_item

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

/* [<][>][^][v][top][bottom][index][help] */