git: 78e25e65bf38 - main - lindebugfs: Add `debugfs_create_str()`
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 13 Apr 2025 10:00:55 UTC
The branch main has been updated by dumbbell: URL: https://cgit.FreeBSD.org/src/commit/?id=78e25e65bf381303c8bdac9a713ab7b26a854b8c commit 78e25e65bf381303c8bdac9a713ab7b26a854b8c Author: Jean-Sébastien Pédron <dumbbell@FreeBSD.org> AuthorDate: 2025-02-08 19:10:53 +0000 Commit: Jean-Sébastien Pédron <dumbbell@FreeBSD.org> CommitDate: 2025-04-13 09:50:14 +0000 lindebugfs: Add `debugfs_create_str()` This function is used by the i915 DRM driver starting with Linux 6.8. Reviewed by: bz, emaste Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D49067 --- sys/compat/lindebugfs/lindebugfs.c | 115 +++++++++++++++++++++ sys/compat/linuxkpi/common/include/linux/debugfs.h | 2 + sys/modules/lindebugfs/Makefile | 1 + 3 files changed, 118 insertions(+) diff --git a/sys/compat/lindebugfs/lindebugfs.c b/sys/compat/lindebugfs/lindebugfs.c index 37028b667be8..97f73e79fb6c 100644 --- a/sys/compat/lindebugfs/lindebugfs.c +++ b/sys/compat/lindebugfs/lindebugfs.c @@ -624,6 +624,121 @@ debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, a } +static int +fops_str_open(struct inode *inode, struct file *filp) +{ + + return (simple_open(inode, filp)); +} + +static ssize_t +fops_str_read(struct file *filp, char __user *ubuf, size_t read_size, + loff_t *ppos) +{ + ssize_t ret; + char *str, *str_with_newline; + size_t str_len, str_with_newline_len; + + if (filp->private_data == NULL) + return (-EINVAL); + + str = *(char **)filp->private_data; + str_len = strlen(str); + + /* + * `str_with_newline` is terminated with a newline, but is not + * NUL-terminated. + */ + str_with_newline_len = str_len + 1; + str_with_newline = kmalloc(str_with_newline_len, GFP_KERNEL); + if (str_with_newline == NULL) + return (-ENOMEM); + + strncpy(str_with_newline, str, str_len); + str_with_newline[str_len] = '\n'; + + ret = simple_read_from_buffer(ubuf, read_size, ppos, + str_with_newline, str_with_newline_len); + + kfree(str_with_newline); + + return (ret); +} + +static ssize_t +fops_str_write(struct file *filp, const char *buf, size_t write_size, + loff_t *ppos) +{ + char *old, *new; + size_t old_len, new_len; + + if (filp->private_data == NULL) + return (-EINVAL); + + old = *(char **)filp->private_data; + new = NULL; + + /* + * We enforce concatenation of the newly written value to the existing + * value. + */ + old_len = strlen(old); + if (*ppos && *ppos != old_len) + return (-EINVAL); + + new_len = old_len + write_size; + if (new_len + 1 > PAGE_SIZE) + return (-E2BIG); + + new = kmalloc(new_len + 1, GFP_KERNEL); + if (new == NULL) + return (-ENOMEM); + + memcpy(new, old, old_len); + if (copy_from_user(new + old_len, buf, write_size) != 0) { + kfree(new); + return (-EFAULT); + } + + new[new_len] = '\0'; + strim(new); + + filp->private_data = &new; + + kfree(old); + + return (write_size); +} + +static const struct file_operations fops_str = { + .owner = THIS_MODULE, + .open = fops_str_open, + .read = fops_str_read, + .write = fops_str_write, + .llseek = no_llseek +}; +static const struct file_operations fops_str_ro = { + .owner = THIS_MODULE, + .open = fops_str_open, + .read = fops_str_read, + .llseek = no_llseek +}; +static const struct file_operations fops_str_wo = { + .owner = THIS_MODULE, + .open = fops_str_open, + .write = fops_str_write, + .llseek = no_llseek +}; + +void +debugfs_create_str(const char *name, umode_t mode, struct dentry *parent, + char **value) +{ + debugfs_create_mode_unsafe(name, mode, parent, value, + &fops_str, &fops_str_ro, &fops_str_wo); +} + + static ssize_t fops_blob_read(struct file *filp, char __user *ubuf, size_t read_size, loff_t *ppos) { diff --git a/sys/compat/linuxkpi/common/include/linux/debugfs.h b/sys/compat/linuxkpi/common/include/linux/debugfs.h index 54145b61503e..4d146e085a7b 100644 --- a/sys/compat/linuxkpi/common/include/linux/debugfs.h +++ b/sys/compat/linuxkpi/common/include/linux/debugfs.h @@ -115,6 +115,8 @@ void debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); void debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value); +void debugfs_create_str(const char *name, umode_t mode, struct dentry *parent, + char **value); struct dentry *debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *value); diff --git a/sys/modules/lindebugfs/Makefile b/sys/modules/lindebugfs/Makefile index dce9a2a3e955..44041011b407 100644 --- a/sys/modules/lindebugfs/Makefile +++ b/sys/modules/lindebugfs/Makefile @@ -14,6 +14,7 @@ EXPORT_SYMS+= debugfs_create_file EXPORT_SYMS+= debugfs_create_file_size EXPORT_SYMS+= debugfs_create_file_unsafe EXPORT_SYMS+= debugfs_create_mode_unsafe +EXPORT_SYMS+= debugfs_create_str EXPORT_SYMS+= debugfs_create_symlink EXPORT_SYMS+= debugfs_create_u8 EXPORT_SYMS+= debugfs_create_u16