fs/pstore/ftrace.c

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

File Facts

System
Linux kernel
Corpus path
fs/pstore/ftrace.c
Extension
.c
Size
5448 bytes
Lines
231
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_knob_fops = {
	.open	= simple_open,
	.read	= pstore_ftrace_knob_read,
	.write	= pstore_ftrace_knob_write,
};

static struct dentry *pstore_ftrace_dir;

void pstore_register_ftrace(void)
{
	if (!psinfo->write)
		return;

	pstore_ftrace_dir = debugfs_create_dir("pstore", NULL);

	pstore_set_ftrace_enabled(record_ftrace);

	debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir, NULL,
			    &pstore_knob_fops);
}

void pstore_unregister_ftrace(void)
{
	mutex_lock(&pstore_ftrace_lock);
	if (record_ftrace) {
		unregister_ftrace_function(&pstore_ftrace_ops);
		record_ftrace = false;
	}
	mutex_unlock(&pstore_ftrace_lock);

	debugfs_remove_recursive(pstore_ftrace_dir);
}

ssize_t pstore_ftrace_combine_log(char **dest_log, size_t *dest_log_size,
				  const char *src_log, size_t src_log_size)
{
	size_t dest_size, src_size, total, dest_off, src_off;
	size_t dest_idx = 0, src_idx = 0, merged_idx = 0;
	void *merged_buf;
	struct pstore_ftrace_record *drec, *srec, *mrec;
	size_t record_size = sizeof(struct pstore_ftrace_record);

	dest_off = *dest_log_size % record_size;
	dest_size = *dest_log_size - dest_off;

	src_off = src_log_size % record_size;
	src_size = src_log_size - src_off;

	total = dest_size + src_size;
	merged_buf = kmalloc(total, GFP_KERNEL);
	if (!merged_buf)
		return -ENOMEM;

	drec = (struct pstore_ftrace_record *)(*dest_log + dest_off);
	srec = (struct pstore_ftrace_record *)(src_log + src_off);
	mrec = (struct pstore_ftrace_record *)(merged_buf);

	while (dest_size > 0 && src_size > 0) {
		if (pstore_ftrace_read_timestamp(&drec[dest_idx]) <
		    pstore_ftrace_read_timestamp(&srec[src_idx])) {
			mrec[merged_idx++] = drec[dest_idx++];
			dest_size -= record_size;
		} else {
			mrec[merged_idx++] = srec[src_idx++];
			src_size -= record_size;
		}
	}

	while (dest_size > 0) {
		mrec[merged_idx++] = drec[dest_idx++];
		dest_size -= record_size;
	}

	while (src_size > 0) {
		mrec[merged_idx++] = srec[src_idx++];
		src_size -= record_size;
	}

	kfree(*dest_log);
	*dest_log = merged_buf;
	*dest_log_size = total;

	return 0;
}
EXPORT_SYMBOL_GPL(pstore_ftrace_combine_log);

Annotation

Implementation Notes