fs/tracefs/inode.c

Source file repositories/reference/linux-study-clean/fs/tracefs/inode.c

File Facts

System
Linux kernel
Corpus path
fs/tracefs/inode.c
Extension
.c
Size
21609 bytes
Lines
810
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

static const struct file_operations tracefs_file_operations = {
	.read =		default_read_file,
	.write =	default_write_file,
	.open =		simple_open,
	.llseek =	noop_llseek,
};

static struct tracefs_dir_ops {
	int (*mkdir)(const char *name);
	int (*rmdir)(const char *name);
} tracefs_ops __ro_after_init;

static struct dentry *tracefs_syscall_mkdir(struct mnt_idmap *idmap,
					    struct inode *inode, struct dentry *dentry,
					    umode_t mode)
{
	struct tracefs_inode *ti;
	struct name_snapshot name;
	int ret;

	/*
	 * This is a new directory that does not take the default of
	 * the rootfs. It becomes the default permissions for all the
	 * files and directories underneath it.
	 */
	ti = get_tracefs(inode);
	ti->flags |= TRACEFS_INSTANCE_INODE;
	ti->private = inode;

	/*
	 * The mkdir call can call the generic functions that create
	 * the files within the tracefs system. It is up to the individual
	 * mkdir routine to handle races.
	 */
	take_dentry_name_snapshot(&name, dentry);
	inode_unlock(inode);
	ret = tracefs_ops.mkdir(name.name.name);
	inode_lock(inode);
	release_dentry_name_snapshot(&name);

	return ERR_PTR(ret);
}

static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
{
	struct name_snapshot name;
	int ret;

	/*
	 * The rmdir call can call the generic functions that create
	 * the files within the tracefs system. It is up to the individual
	 * rmdir routine to handle races.
	 * This time we need to unlock not only the parent (inode) but
	 * also the directory that is being deleted.
	 */
	take_dentry_name_snapshot(&name, dentry);
	inode_unlock(inode);
	inode_unlock(d_inode(dentry));

	ret = tracefs_ops.rmdir(name.name.name);

	inode_lock_nested(inode, I_MUTEX_PARENT);
	inode_lock(d_inode(dentry));
	release_dentry_name_snapshot(&name);

	return ret;
}

static void set_tracefs_inode_owner(struct inode *inode)
{
	struct tracefs_inode *ti = get_tracefs(inode);
	struct inode *root_inode = ti->private;
	kuid_t uid;
	kgid_t gid;

	uid = root_inode->i_uid;
	gid = root_inode->i_gid;

	/*
	 * If the root is not the mount point, then check the root's
	 * permissions. If it was never set, then default to the
	 * mount point.
	 */
	if (root_inode != d_inode(root_inode->i_sb->s_root)) {
		struct tracefs_inode *rti;

		rti = get_tracefs(root_inode);
		root_inode = d_inode(root_inode->i_sb->s_root);

		if (!(rti->flags & TRACEFS_UID_PERM_SET))

Annotation

Implementation Notes