fs/pstore/inode.c

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

File Facts

System
Linux kernel
Corpus path
fs/pstore/inode.c
Extension
.c
Size
11965 bytes
Lines
529
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 pstore_file_operations = {
	.open		= pstore_file_open,
	.read		= pstore_file_read,
	.llseek		= pstore_file_llseek,
	.release	= seq_release,
};

/*
 * When a file is unlinked from our file system we call the
 * platform driver to erase the record from persistent store.
 */
static int pstore_unlink(struct inode *dir, struct dentry *dentry)
{
	struct pstore_private *p = d_inode(dentry)->i_private;
	struct pstore_record *record = p->record;

	if (!record->psi->erase)
		return -EPERM;

	/* Make sure we can't race while removing this file. */
	scoped_guard(mutex, &records_list_lock) {
		if (!list_empty(&p->list))
			list_del_init(&p->list);
		else
			return -ENOENT;
		p->dentry = NULL;
	}

	scoped_guard(mutex, &record->psi->read_mutex)
		record->psi->erase(record);

	return simple_unlink(dir, dentry);
}

static void pstore_evict_inode(struct inode *inode)
{
	struct pstore_private	*p = inode->i_private;

	clear_inode(inode);
	free_pstore_private(p);
}

static const struct inode_operations pstore_dir_inode_operations = {
	.lookup		= simple_lookup,
	.unlink		= pstore_unlink,
};

static struct inode *pstore_get_inode(struct super_block *sb)
{
	struct inode *inode = new_inode(sb);
	if (inode) {
		inode->i_ino = get_next_ino();
		simple_inode_init_ts(inode);
	}
	return inode;
}

enum {
	Opt_kmsg_bytes
};

static const struct fs_parameter_spec pstore_param_spec[] = {
	fsparam_u32	("kmsg_bytes",	Opt_kmsg_bytes),
	{}
};

struct pstore_context {
	unsigned int kmsg_bytes;
};

static int pstore_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
	struct pstore_context *ctx = fc->fs_private;
	struct fs_parse_result result;
	int opt;

	opt = fs_parse(fc, pstore_param_spec, param, &result);
	/* pstore has historically ignored invalid kmsg_bytes param */
	if (opt < 0)
		return 0;

	switch (opt) {
	case Opt_kmsg_bytes:
		ctx->kmsg_bytes = result.uint_32;
		break;
	default:
		return -EINVAL;
	}

	return 0;

Annotation

Implementation Notes