fs/kernfs/mount.c

Source file repositories/reference/linux-study-clean/fs/kernfs/mount.c

File Facts

System
Linux kernel
Corpus path
fs/kernfs/mount.c
Extension
.c
Size
12071 bytes
Lines
473
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source 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

scoped_guard(rwsem_read, &root->kernfs_rwsem) {
			kntmp = find_next_ancestor(kn, knparent);
			if (WARN_ON(!kntmp)) {
				dput(dentry);
				return ERR_PTR(-EINVAL);
			}
			name = kstrdup(kernfs_rcu_name(kntmp), GFP_KERNEL);
		}
		if (!name) {
			dput(dentry);
			return ERR_PTR(-ENOMEM);
		}
		dtmp = lookup_noperm_positive_unlocked(&QSTR(name), dentry);
		dput(dentry);
		kfree(name);
		if (IS_ERR(dtmp))
			return dtmp;
		knparent = kntmp;
		dentry = dtmp;
	} while (true);
}

static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *kfc)
{
	struct kernfs_super_info *info = kernfs_info(sb);
	struct kernfs_root *kf_root = kfc->root;
	struct inode *inode;
	struct dentry *root;

	info->sb = sb;
	/* Userspace would break if executables or devices appear on sysfs */
	sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV;
	sb->s_blocksize = PAGE_SIZE;
	sb->s_blocksize_bits = PAGE_SHIFT;
	sb->s_magic = kfc->magic;
	sb->s_op = &kernfs_sops;
	sb->s_xattr = kernfs_xattr_handlers;
	if (info->root->flags & KERNFS_ROOT_SUPPORT_EXPORTOP)
		sb->s_export_op = &kernfs_export_ops;
	sb->s_time_gran = 1;
	sb->s_maxbytes  = MAX_LFS_FILESIZE;

	/* sysfs dentries and inodes don't require IO to create */
	sb->s_shrink->seeks = 0;

	/* get root inode, initialize and unlock it */
	down_read(&kf_root->kernfs_rwsem);
	inode = kernfs_get_inode(sb, info->root->kn);
	up_read(&kf_root->kernfs_rwsem);
	if (!inode) {
		pr_debug("kernfs: could not get root inode\n");
		return -ENOMEM;
	}

	/* instantiate and link root dentry */
	root = d_make_root(inode);
	if (!root) {
		pr_debug("%s: could not get root dentry!\n", __func__);
		return -ENOMEM;
	}
	sb->s_root = root;
	set_default_d_op(sb, &kernfs_dops);
	return 0;
}

static int kernfs_test_super(struct super_block *sb, struct fs_context *fc)
{
	struct kernfs_super_info *sb_info = kernfs_info(sb);
	struct kernfs_super_info *info = fc->s_fs_info;

	return sb_info->root == info->root && sb_info->ns == info->ns;
}

static int kernfs_set_super(struct super_block *sb, struct fs_context *fc)
{
	struct kernfs_fs_context *kfc = fc->fs_private;

	kfc->ns_tag = NULL;
	return set_anon_super_fc(sb, fc);
}

/**
 * kernfs_super_ns - determine the namespace tag of a kernfs super_block
 * @sb: super_block of interest
 *
 * Return: the namespace tag associated with kernfs super_block @sb.
 */
const struct ns_common *kernfs_super_ns(struct super_block *sb)
{
	struct kernfs_super_info *info = kernfs_info(sb);

Annotation

Implementation Notes