fs/configfs/item.c

Source file repositories/reference/linux-study-clean/fs/configfs/item.c

File Facts

System
Linux kernel
Corpus path
fs/configfs/item.c
Extension
.c
Size
4759 bytes
Lines
191
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * item.c - library routines for handling generic config items
 *
 * Based on kobject:
 *	kobject is Copyright (c) 2002-2003 Patrick Mochel
 *
 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
 *
 * Please see the file Documentation/filesystems/configfs.rst for
 * critical information about using the config_item interface.
 */

#include <linux/string.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/slab.h>

#include <linux/configfs.h>


static inline struct config_item *to_item(struct list_head *entry)
{
	return container_of(entry, struct config_item, ci_entry);
}

/* Evil kernel */
static void config_item_release(struct kref *kref);

/**
 *	config_item_init - initialize item.
 *	@item:	item in question.
 */
static void config_item_init(struct config_item *item)
{
	kref_init(&item->ci_kref);
	INIT_LIST_HEAD(&item->ci_entry);
}

/**
 *	config_item_set_name - Set the name of an item
 *	@item:	item.
 *	@fmt:  The vsnprintf()'s format string.
 *
 *	If strlen(name) >= CONFIGFS_ITEM_NAME_LEN, then use a
 *	dynamically allocated string that @item->ci_name points to.
 *	Otherwise, use the static @item->ci_namebuf array.
 */
int config_item_set_name(struct config_item *item, const char *fmt, ...)
{
	int limit = CONFIGFS_ITEM_NAME_LEN;
	int need;
	va_list args;
	char *name;

	/*
	 * First, try the static array
	 */
	va_start(args, fmt);
	need = vsnprintf(item->ci_namebuf, limit, fmt, args);
	va_end(args);
	if (need < limit)
		name = item->ci_namebuf;
	else {
		va_start(args, fmt);
		name = kvasprintf(GFP_KERNEL, fmt, args);
		va_end(args);
		if (!name)
			return -ENOMEM;
	}

	/* Free the old name, if necessary. */
	if (item->ci_name && item->ci_name != item->ci_namebuf)
		kfree(item->ci_name);

	/* Now, set the new name */
	item->ci_name = name;
	return 0;
}
EXPORT_SYMBOL(config_item_set_name);

void config_item_init_type_name(struct config_item *item,
				const char *name,
				const struct config_item_type *type)
{
	config_item_set_name(item, "%s", name);
	item->ci_type = type;
	config_item_init(item);
}
EXPORT_SYMBOL(config_item_init_type_name);

Annotation

Implementation Notes