fs/configfs/dir.c

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

File Facts

System
Linux kernel
Corpus path
fs/configfs/dir.c
Extension
.c
Size
52146 bytes
Lines
1981
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: operation-table or driver-model contract
Status
pattern 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

const struct file_operations configfs_dir_operations = {
	.open		= configfs_dir_open,
	.release	= configfs_dir_close,
	.llseek		= configfs_dir_lseek,
	.read		= generic_read_dir,
	.iterate_shared	= configfs_readdir,
};

/**
 * configfs_register_group - creates a parent-child relation between two groups
 * @parent_group:	parent group
 * @group:		child group
 *
 * link groups, creates dentry for the child and attaches it to the
 * parent dentry.
 *
 * Return: 0 on success, negative errno code on error
 */
int configfs_register_group(struct config_group *parent_group,
			    struct config_group *group)
{
	struct configfs_subsystem *subsys = parent_group->cg_subsys;
	struct dentry *parent;
	struct configfs_fragment *frag;
	int ret;

	frag = new_fragment();
	if (!frag)
		return -ENOMEM;

	mutex_lock(&subsys->su_mutex);
	link_group(parent_group, group);
	mutex_unlock(&subsys->su_mutex);

	parent = parent_group->cg_item.ci_dentry;

	inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
	ret = create_default_group(parent, group, frag);
	if (ret)
		goto err_out;

	spin_lock(&configfs_dirent_lock);
	configfs_dir_set_ready(group->cg_item.ci_dentry->d_fsdata);
	spin_unlock(&configfs_dirent_lock);
	inode_unlock(d_inode(parent));
	put_fragment(frag);
	return 0;
err_out:
	inode_unlock(d_inode(parent));
	mutex_lock(&subsys->su_mutex);
	unlink_group(group);
	mutex_unlock(&subsys->su_mutex);
	put_fragment(frag);
	return ret;
}
EXPORT_SYMBOL(configfs_register_group);

/**
 * configfs_unregister_group() - unregisters a child group from its parent
 * @group: parent group to be unregistered
 *
 * Undoes configfs_register_group()
 */
void configfs_unregister_group(struct config_group *group)
{
	struct configfs_subsystem *subsys = group->cg_subsys;
	struct dentry *dentry = dget(group->cg_item.ci_dentry);
	struct dentry *parent = group->cg_item.ci_parent->ci_dentry;
	struct configfs_dirent *sd = dentry->d_fsdata;
	struct configfs_fragment *frag = sd->s_frag;

	down_write(&frag->frag_sem);
	frag->frag_dead = true;
	up_write(&frag->frag_sem);

	inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
	spin_lock(&configfs_dirent_lock);
	configfs_detach_prep(sd, NULL);
	spin_unlock(&configfs_dirent_lock);

	configfs_detach_group(dentry);
	d_inode(dentry)->i_flags |= S_DEAD;
	dont_mount(dentry);
	d_drop(dentry);
	fsnotify_rmdir(d_inode(parent), dentry);
	inode_unlock(d_inode(parent));

	dput(dentry);

	mutex_lock(&subsys->su_mutex);

Annotation

Implementation Notes