fs/openpromfs/inode.c

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

File Facts

System
Linux kernel
Corpus path
fs/openpromfs/inode.c
Extension
.c
Size
9965 bytes
Lines
476
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 openpromfs_prop_ops = {
	.open		= property_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static int openpromfs_readdir(struct file *, struct dir_context *);

static const struct file_operations openprom_operations = {
	.read		= generic_read_dir,
	.iterate_shared	= openpromfs_readdir,
	.llseek		= generic_file_llseek,
};

static struct dentry *openpromfs_lookup(struct inode *, struct dentry *, unsigned int);

static const struct inode_operations openprom_inode_operations = {
	.lookup		= openpromfs_lookup,
};

static struct dentry *openpromfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{
	struct op_inode_info *ent_oi, *oi = OP_I(dir);
	struct device_node *dp, *child;
	struct property *prop;
	enum op_inode_type ent_type;
	union op_inode_data ent_data;
	const char *name;
	struct inode *inode;
	unsigned int ino;
	int len;
	
	BUG_ON(oi->type != op_inode_node);

	dp = oi->u.node;

	name = dentry->d_name.name;
	len = dentry->d_name.len;

	mutex_lock(&op_mutex);

	child = dp->child;
	while (child) {
		const char *node_name = kbasename(child->full_name);
		int n = strlen(node_name);

		if (len == n &&
		    !strncmp(node_name, name, len)) {
			ent_type = op_inode_node;
			ent_data.node = child;
			ino = child->unique_id;
			goto found;
		}
		child = child->sibling;
	}

	prop = dp->properties;
	while (prop) {
		int n = strlen(prop->name);

		if (len == n && !strncmp(prop->name, name, len)) {
			ent_type = op_inode_prop;
			ent_data.prop = prop;
			ino = prop->unique_id;
			goto found;
		}

		prop = prop->next;
	}

	mutex_unlock(&op_mutex);
	return ERR_PTR(-ENOENT);

found:
	inode = openprom_iget(dir->i_sb, ino);
	mutex_unlock(&op_mutex);
	if (IS_ERR(inode))
		return ERR_CAST(inode);
	if (inode_state_read_once(inode) & I_NEW) {
		simple_inode_init_ts(inode);
		ent_oi = OP_I(inode);
		ent_oi->type = ent_type;
		ent_oi->u = ent_data;

		switch (ent_type) {
		case op_inode_node:
			inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
			inode->i_op = &openprom_inode_operations;
			inode->i_fop = &openprom_operations;

Annotation

Implementation Notes