fs/sysfs/group.c

Source file repositories/reference/linux-study-clean/fs/sysfs/group.c

File Facts

System
Linux kernel
Corpus path
fs/sysfs/group.c
Extension
.c
Size
16767 bytes
Lines
639
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

if (grp->is_visible || grp->is_visible_const) {
				if (grp->is_visible)
					mode = grp->is_visible(kobj, *attr, i);
				else
					mode = grp->is_visible_const(kobj, *attr, i);
				mode &= ~SYSFS_GROUP_INVISIBLE;
				if (!mode)
					continue;
			}

			WARN(mode & ~(SYSFS_PREALLOC | 0664),
			     "Attribute %s: Invalid permissions 0%o\n",
			     (*attr)->name, mode);

			mode &= SYSFS_PREALLOC | 0664;
			error = sysfs_add_file_mode_ns(parent, *attr, mode, uid,
						       gid, NULL);
			if (unlikely(error))
				break;
		}
		if (error) {
			remove_files(parent, grp);
			goto exit;
		}
	}

	if (grp->bin_attrs) {
		for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) {
			umode_t mode = (*bin_attr)->attr.mode;
			size_t size = (*bin_attr)->size;

			if (update)
				kernfs_remove_by_name(parent,
						(*bin_attr)->attr.name);
			if (grp->is_bin_visible) {
				mode = grp->is_bin_visible(kobj, *bin_attr, i);
				mode &= ~SYSFS_GROUP_INVISIBLE;
				if (!mode)
					continue;
			}
			if (grp->bin_size)
				size = grp->bin_size(kobj, *bin_attr, i);

			WARN(mode & ~(SYSFS_PREALLOC | 0664),
			     "Attribute %s: Invalid permissions 0%o\n",
			     (*bin_attr)->attr.name, mode);

			mode &= SYSFS_PREALLOC | 0664;
			error = sysfs_add_bin_file_mode_ns(parent, *bin_attr,
							   mode, size, uid, gid,
							   NULL);
			if (error)
				break;
		}
		if (error)
			remove_files(parent, grp);
	}
exit:
	return error;
}


static int internal_create_group(struct kobject *kobj, int update,
				 const struct attribute_group *grp)
{
	struct kernfs_node *kn;
	kuid_t uid;
	kgid_t gid;
	int error;

	if (WARN_ON(!kobj || (!update && !kobj->sd)))
		return -EINVAL;

	/* Updates may happen before the object has been instantiated */
	if (unlikely(update && !kobj->sd))
		return -EINVAL;

	if (!grp->attrs && !grp->bin_attrs) {
		pr_debug("sysfs: (bin_)attrs not set by subsystem for group: %s/%s, skipping\n",
			 kobj->name, grp->name ?: "");
		return 0;
	}

	kobject_get_ownership(kobj, &uid, &gid);
	if (grp->name) {
		umode_t mode = __first_visible(grp, kobj);

		if (mode & SYSFS_GROUP_INVISIBLE)
			mode = 0;
		else

Annotation

Implementation Notes