Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135525949
D35883.id108583.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D35883.id108583.diff
View Options
diff --git a/sys/compat/lindebugfs/lindebugfs.c b/sys/compat/lindebugfs/lindebugfs.c
--- a/sys/compat/lindebugfs/lindebugfs.c
+++ b/sys/compat/lindebugfs/lindebugfs.c
@@ -69,9 +69,9 @@
#include <compat/linux/linux_util.h>
#include <fs/pseudofs/pseudofs.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
#include <linux/compat.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
MALLOC_DEFINE(M_DFSINT, "debugfsint", "Linux debugfs internal");
@@ -117,48 +117,40 @@
debugfs_fill(PFS_FILL_ARGS)
{
struct dentry_meta *d;
- struct linux_file lf = {};
- struct seq_file *sf;
+ struct linux_file lf;
struct vnode vn;
- void *buf;
+ char buf[sb->s_size];
int rc;
- size_t len;
- off_t off;
-
- d = pn->pn_data;
+ off_t off = 0;
if ((rc = linux_set_current_flags(curthread, M_NOWAIT)))
return (rc);
+
+ d = pn->pn_data;
vn.v_data = d->dm_data;
- if (uio->uio_rw == UIO_READ) {
- buf = uio->uio_iov[0].iov_base;
- len = min(uio->uio_iov[0].iov_len, uio->uio_resid);
- } else {
- sbuf_finish(sb);
- buf = sbuf_data(sb);
- len = sbuf_len(sb);
- }
- off = 0;
+
+ /* seq_file requires sbuf for r/w */
+ lf.private_data = (void *) sb;
+
rc = d->dm_fops->open(&vn, &lf);
if (rc < 0) {
#ifdef INVARIANTS
printf("%s:%d open failed with %d\n", __FUNCTION__, __LINE__, rc);
#endif
- return (-rc);
+ return (rc);
}
- sf = lf.private_data;
- sf->buf = sb;
- if (uio->uio_rw == UIO_READ) {
- if (d->dm_fops->read)
- rc = d->dm_fops->read(&lf, NULL, len, &off);
- else
- rc = -ENODEV;
- } else {
- if (d->dm_fops->write)
- rc = d->dm_fops->write(&lf, buf, len, &off);
- else
- rc = -ENODEV;
+
+ rc = -ENODEV;
+ if (uio->uio_rw == UIO_READ && d->dm_fops->read) {
+ buf[0] = '\0';
+ rc = d->dm_fops->read(&lf, buf, sizeof(buf), &off);
+ if (strlen(buf) > 0)
+ sbuf_bcpy(sb, buf, strlen(buf));
+ } else if (uio->uio_rw == UIO_WRITE && d->dm_fops->write) {
+ sbuf_finish(sb);
+ rc = d->dm_fops->write(&lf, sbuf_data(sb), sbuf_len(sb), &off);
}
+
if (d->dm_fops->release)
d->dm_fops->release(&vn, &lf);
else
@@ -168,7 +160,7 @@
#ifdef INVARIANTS
printf("%s:%d read/write failed with %d\n", __FUNCTION__, __LINE__, rc);
#endif
- return (-rc);
+ return (rc);
}
return (0);
}
@@ -218,6 +210,37 @@
return (dnode);
}
+/*
+ * NOTE: The _unsafe moniker denotes that @fops are not protected against debugfs
+ * file removals. This behavior is not implemented in FreeBSD at this time.
+ */
+struct dentry *
+debugfs_create_file_unsafe(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops)
+{
+ return (debugfs_create_file(name, mode, parent, data, fops));
+}
+
+struct dentry *
+debugfs_create_mode_unsafe(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops,
+ const struct file_operations *fops_ro,
+ const struct file_operations *fops_wo)
+{
+ umode_t read = mode & S_IRUGO;
+ umode_t write = mode & S_IWUGO;
+
+ if (read && !write)
+ return (debugfs_create_file_unsafe(name, mode, parent, data, fops_ro));
+
+ if (write && !read)
+ return (debugfs_create_file_unsafe(name, mode, parent, data, fops_wo));
+
+ return (debugfs_create_file_unsafe(name, mode, parent, data, fops));
+}
+
struct dentry *
debugfs_create_dir(const char *name, struct dentry *parent)
{
@@ -299,6 +322,74 @@
pfs_destroy(dnode->d_pfs_node);
}
+static int
+debugfs_bool_get(void *data, uint64_t *ullval)
+{
+ bool *bval = data;
+
+ if (*bval)
+ *ullval = 1;
+ else
+ *ullval = 0;
+
+ return (0);
+}
+
+static int
+debugfs_bool_set(void *data, uint64_t ullval)
+{
+ bool *bval = data;
+
+ if (ullval)
+ *bval = 1;
+ else
+ *bval = 0;
+
+ return (0);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_bool, debugfs_bool_get, debugfs_bool_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_bool_ro, debugfs_bool_get, NULL, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_bool_wo, NULL, debugfs_bool_set, "%llu\n");
+
+void
+debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent,
+ bool *value)
+{
+ debugfs_create_mode_unsafe(name, mode, parent, value, &fops_bool,
+ &fops_bool_ro, &fops_bool_wo);
+ return;
+}
+
+static int
+debugfs_ulong_get(void *data, uint64_t *value)
+{
+ uint64_t *uldata = data;
+ *value = *uldata;
+ return (0);
+}
+
+static int
+debugfs_ulong_set(void *data, uint64_t value)
+{
+ uint64_t *uldata = data;
+ *uldata = value;
+ return (0);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong, debugfs_ulong_get, debugfs_ulong_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_ro, debugfs_ulong_get, NULL, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n");
+
+void
+debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent,
+ unsigned long *value)
+{
+ debugfs_create_mode_unsafe(name, mode, parent, value, &fops_ulong,
+ &fops_ulong_ro, &fops_ulong_wo);
+ return;
+}
+
static int
debugfs_init(PFS_INIT_ARGS)
{
@@ -321,4 +412,9 @@
#else
PSEUDOFS(debugfs, 1, VFCF_JAIL);
#endif
+
+/* Module specifications */
+static moduledata_t lindebugfs_data = { "lindebugfs", NULL, NULL };
+DECLARE_MODULE(lindebugfs, lindebugfs_data, SI_SUB_EXEC, SI_ORDER_MIDDLE);
+MODULE_VERSION(lindebugfs, 1);
MODULE_DEPEND(lindebugfs, linuxkpi, 1, 1, 1);
diff --git a/sys/compat/linuxkpi/common/include/linux/dcache.h b/sys/compat/linuxkpi/common/include/linux/dcache.h
--- a/sys/compat/linuxkpi/common/include/linux/dcache.h
+++ b/sys/compat/linuxkpi/common/include/linux/dcache.h
@@ -29,8 +29,9 @@
#ifndef _LINUXKPI_LINUX_DCACHE_H
#define _LINUXKPI_LINUX_DCACHE_H
-struct vnode;
-struct pfs_node;
+#include <sys/vnode.h>
+
+#include <fs/pseudofs/pseudofs.h>
struct dentry {
struct vnode *d_inode;
diff --git a/sys/compat/linuxkpi/common/include/linux/debugfs.h b/sys/compat/linuxkpi/common/include/linux/debugfs.h
--- a/sys/compat/linuxkpi/common/include/linux/debugfs.h
+++ b/sys/compat/linuxkpi/common/include/linux/debugfs.h
@@ -31,21 +31,52 @@
#define _LINUXKPI_LINUX_DEBUGFS_H_
#include <linux/fs.h>
+#include <linux/module.h>
#include <linux/seq_file.h>
-
#include <linux/types.h>
-void debugfs_remove(struct dentry *dentry);
+MALLOC_DECLARE(M_DFSINT);
+
+struct debugfs_reg32 {
+ char *name;
+ unsigned long offset;
+};
+
+struct debugfs_regset32 {
+ const struct debugfs_reg32 *regs;
+ int nregs;
+};
struct dentry *debugfs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
+struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops);
+
+struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
+ struct dentry *parent, void *data,
+ const struct file_operations *fops,
+ const struct file_operations *fops_ro,
+ const struct file_operations *fops_wo);
+
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
const char *dest);
+void debugfs_remove(struct dentry *dentry);
+
void debugfs_remove_recursive(struct dentry *dentry);
-#endif
+#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
+ DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)
+
+void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent,
+ bool *value);
+
+void debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent,
+ unsigned long *value);
+
+#endif /* _LINUXKPI_LINUX_DEBUGFS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h
--- a/sys/compat/linuxkpi/common/include/linux/fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/fs.h
@@ -45,6 +45,8 @@
#include <linux/dcache.h>
#include <linux/capability.h>
#include <linux/wait_bit.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
struct module;
struct kiocb;
@@ -250,6 +252,7 @@
static inline int
simple_open(struct inode *inode, struct file *filp)
{
+ filp->private_data = inode->i_private;
return 0;
}
@@ -296,6 +299,7 @@
return (-ESPIPE);
}
+#define default_llseek no_llseek
static inline loff_t
noop_llseek(struct linux_file *file, loff_t offset, int whence)
@@ -318,4 +322,76 @@
return (file->f_op->mmap(file, vma));
}
+static inline void
+i_size_write(struct inode *inode, loff_t i_size)
+{
+ /* inode->i_size = i_size; */
+ return;
+}
+
+/*
+ * simple_read_from_buffer: copy data from kernel-space origin
+ * buffer into user-space destination buffer
+ *
+ * @dest: destination buffer
+ * @read_size: number of bytes to be transferred
+ * @ppos: starting transfer position pointer
+ * @orig: origin buffer
+ * @buf_size: size of destination and origin buffers
+ *
+ * Return value:
+ * On success, total bytes copied with *ppos incremented accordingly.
+ * On failure, negative value.
+ */
+static inline ssize_t
+simple_read_from_buffer(void __user *dest, size_t read_size, loff_t *ppos,
+ void *orig, size_t buf_size)
+{
+ void *read_pos = ((char *) orig) + *ppos;
+ size_t buf_remain = buf_size - *ppos;
+ ssize_t num_read;
+
+ if (buf_remain < 0 || buf_remain > buf_size)
+ return -EINVAL;
+
+ if (read_size > buf_remain)
+ read_size = buf_remain;
+
+ /* copy_to_user returns number of bytes NOT read */
+ num_read = read_size - copy_to_user(dest, read_pos, read_size);
+ if (num_read == 0)
+ return -EFAULT;
+ *ppos += num_read;
+
+ return (num_read);
+}
+
+MALLOC_DECLARE(M_LSATTR);
+
+#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \
+static inline int \
+__fops ## _open(struct inode *inode, struct file *filp) \
+{ \
+ return (simple_attr_open(inode, filp, __get, __set, __fmt)); \
+} \
+static const struct file_operations __fops = { \
+ .owner = THIS_MODULE, \
+ .open = __fops ## _open, \
+ .release = simple_attr_release, \
+ .read = simple_attr_read, \
+ .write = simple_attr_write, \
+ .llseek = no_llseek \
+}
+
+int simple_attr_open(struct inode *inode, struct file *filp,
+ int (*get)(void *, uint64_t *), int (*set)(void *, uint64_t),
+ const char *fmt);
+
+int simple_attr_release(struct inode *inode, struct file *filp);
+
+ssize_t simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t *ppos);
+
+ssize_t simple_attr_write(struct file *filp, const char __user *buf,
+ size_t write_size, loff_t *ppos);
+
#endif /* _LINUXKPI_LINUX_FS_H_ */
diff --git a/sys/compat/linuxkpi/common/include/linux/seq_file.h b/sys/compat/linuxkpi/common/include/linux/seq_file.h
--- a/sys/compat/linuxkpi/common/include/linux/seq_file.h
+++ b/sys/compat/linuxkpi/common/include/linux/seq_file.h
@@ -32,11 +32,12 @@
#include <linux/types.h>
#include <linux/fs.h>
-#include <sys/sbuf.h>
#undef file
#define inode vnode
+MALLOC_DECLARE(M_LSEQ);
+
#define DEFINE_SHOW_ATTRIBUTE(__name) \
static int __name ## _open(struct inode *inode, struct linux_file *file) \
{ \
@@ -51,11 +52,8 @@
.release = single_release, \
}
-struct seq_operations;
-
struct seq_file {
- struct sbuf *buf;
-
+ struct sbuf *buf;
const struct seq_operations *op;
const struct linux_file *file;
void *private;
@@ -78,7 +76,8 @@
int single_open(struct linux_file *, int (*)(struct seq_file *, void *), void *);
int single_release(struct inode *, struct linux_file *);
-#define seq_printf(m, fmt, ...) sbuf_printf((m)->buf, (fmt), ##__VA_ARGS__)
+void seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
+void seq_printf(struct seq_file *m, const char *fmt, ...);
#define seq_puts(m, str) sbuf_printf((m)->buf, str)
#define seq_putc(m, str) sbuf_putc((m)->buf, str)
diff --git a/sys/compat/linuxkpi/common/include/linux/string.h b/sys/compat/linuxkpi/common/include/linux/string.h
--- a/sys/compat/linuxkpi/common/include/linux/string.h
+++ b/sys/compat/linuxkpi/common/include/linux/string.h
@@ -97,6 +97,20 @@
return (dst);
}
+static inline char *
+strndup_user(const char __user *ustr, long n)
+{
+ char *kstr;
+
+ kstr = memdup_user(ustr, n);
+ if (IS_ERR(kstr))
+ return kstr;
+
+ kstr[n-1] = '\0';
+
+ return (kstr);
+}
+
static inline char *
kstrdup(const char *string, gfp_t gfp)
{
diff --git a/sys/compat/linuxkpi/common/src/linux_seq_file.c b/sys/compat/linuxkpi/common/src/linux_seq_file.c
--- a/sys/compat/linuxkpi/common/src/linux_seq_file.c
+++ b/sys/compat/linuxkpi/common/src/linux_seq_file.c
@@ -48,9 +48,8 @@
struct seq_file *m = f->private_data;
void *p;
int rc;
- off_t pos = 0;
- p = m->op->start(m, &pos);
+ p = m->op->start(m, ppos);
rc = m->op->show(m, p);
if (rc)
return (rc);
@@ -101,15 +100,20 @@
{
struct seq_file *p;
- if (f->private_data != NULL)
- log(LOG_WARNING, "%s private_data not NULL", __func__);
-
if ((p = malloc(sizeof(*p), M_LSEQ, M_NOWAIT|M_ZERO)) == NULL)
return (-ENOMEM);
- f->private_data = p;
+ /*
+ * This seq_file's ->buf is passed in through f->private_data.
+ * A clean seq_file implementation is needed to remove the
+ * FreeBSD sbuf dependency.
+ */
+ if (f->private_data != NULL)
+ p->buf = (struct sbuf *) f->private_data;
+
p->op = op;
p->file = f;
+ f->private_data = (void *) p;
return (0);
}
@@ -160,3 +164,22 @@
free(__DECONST(void *, op), M_LSEQ);
return (rc);
}
+
+void
+seq_vprintf(struct seq_file *m, const char *fmt, va_list args)
+{
+ sbuf_vprintf(m->buf, fmt, args);
+ return;
+}
+
+void
+seq_printf(struct seq_file *m, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ seq_vprintf(m, fmt, args);
+ va_end(args);
+
+ return;
+}
diff --git a/sys/compat/linuxkpi/common/src/linux_simple_attr.c b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
new file mode 100644
--- /dev/null
+++ b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
@@ -0,0 +1,195 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2022, Jake Freeland <jfree@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <linux/fs.h>
+
+MALLOC_DEFINE(M_LSATTR, "simple_attr", "Linux Simple Attribute File");
+
+struct simple_attr {
+ int (*get)(void *, uint64_t *);
+ int (*set)(void *, uint64_t);
+ void *data;
+ const char *fmt;
+ struct mutex mutex;
+};
+
+/*
+ * simple_attr_open: open and populate simple attribute data
+ *
+ * @inode: file inode
+ * @filp: file pointer
+ * @get: ->get() for reading file data
+ * @set: ->set() for writing file data
+ * @fmt: format specifier for data returned by @get
+ *
+ * Memory allocate a simple_attr and appropriately initialize its members.
+ * The simple_attr must be stored in filp->private_data.
+ * Simple attr files do not support seeking. Open the file as nonseekable.
+ *
+ * Return value: simple attribute file descriptor
+ */
+int
+simple_attr_open(struct inode *inode, struct file *filp,
+ int (*get)(void *, uint64_t *), int (*set)(void *, uint64_t),
+ const char *fmt)
+{
+ struct simple_attr *sattr;
+ sattr = malloc(sizeof(*sattr), M_LSATTR, M_ZERO | M_NOWAIT);
+ if (sattr == NULL)
+ return (-ENOMEM);
+
+ sattr->get = get;
+ sattr->set = set;
+ sattr->data = inode->i_private;
+ sattr->fmt = fmt;
+ mutex_init(&sattr->mutex);
+
+ filp->private_data = (void *) sattr;
+
+ return (nonseekable_open(inode, filp));
+}
+
+/*
+ * simple_attr_release: release file's simple attribute data
+ *
+ * @inode: file inode
+ * @filp: file pointer
+ *
+ * Return value: 0
+ */
+int
+simple_attr_release(struct inode *inode, struct file *filp)
+{
+ free(filp->private_data, M_LSATTR);
+ return (0);
+}
+
+/*
+ * simple_attr_read: read simple attr data and transfer into buffer
+ *
+ * @filp: file pointer
+ * @buf: kernel space buffer
+ * @read_size: number of bytes to be transferred
+ * @ppos: starting pointer position for transfer
+ *
+ * The simple_attr structure is stored in filp->private_data.
+ * ->get() retrieves raw file data.
+ * The ->fmt specifier can format this data to be human readable.
+ * This output is then transferred into the @buf buffer.
+ *
+ * Return value:
+ * On success, number of bytes transferred
+ * On failure, negative signed ERRNO
+ */
+ssize_t
+simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t *ppos)
+{
+ struct simple_attr *sattr;
+ uint64_t data;
+ ssize_t ret;
+ char prebuf[24];
+
+ sattr = filp->private_data;
+
+ if (sattr->get == NULL)
+ return (-EFAULT);
+
+ if (*ppos > sizeof(prebuf))
+ return (-EINVAL);
+
+ mutex_lock(&sattr->mutex);
+
+ ret = sattr->get(sattr->data, &data);
+ if (ret)
+ goto unlock;
+
+ scnprintf(prebuf, sizeof(prebuf), sattr->fmt, data);
+ read_size = min((strlen(prebuf) + 1) - *ppos, read_size);
+ ret = strscpy(buf, prebuf + *ppos, read_size);
+
+ /* add 1 for null terminator */
+ if (ret > 0)
+ ret += 1;
+
+unlock:
+ mutex_unlock(&sattr->mutex);
+ return (ret);
+}
+
+/*
+ * simple_attr_write: write contents of buffer into simple attribute file
+ *
+ * @filp: file pointer
+ * @buf: kernel space buffer
+ * @write_size: number bytes to be transferred
+ * @ppos: starting pointer position for transfer
+ *
+ * The simple_attr structure is stored in filp->private_data.
+ * Convert the @buf string to unsigned long long.
+ * ->set() writes unsigned long long data into the simple attr file.
+ *
+ * Return value:
+ * On success, number of bytes written to simple attr
+ * On failure, negative signed ERRNO
+ */
+ssize_t
+simple_attr_write(struct file *filp, const char __user *buf,
+ size_t write_size, loff_t *ppos)
+{
+ struct simple_attr *sattr;
+ unsigned long long data;
+ ssize_t ret;
+
+ sattr = filp->private_data;
+
+ if (sattr->set == NULL)
+ return (-EFAULT);
+
+ if (*ppos > sizeof(data))
+ return (-EINVAL);
+
+ mutex_lock(&sattr->mutex);
+
+ ret = kstrtoull(buf + *ppos, 0, &data);
+ if (ret)
+ goto unlock;
+
+ ret = sattr->set(sattr->data, data);
+ if (ret)
+ goto unlock;
+
+ ret = strlen(buf) - *ppos;
+
+unlock:
+ mutex_unlock(&sattr->mutex);
+ return (ret);
+}
+
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4604,9 +4604,10 @@
compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/lkpi_iic_if.m optional compat_linuxkpi
-compat/linuxkpi/common/src/linux_seq_file.c optional compat_linuxkpi | lindebugfs \
+compat/linuxkpi/common/src/linux_seq_file.c optional compat_linuxkpi | lindebugfs \
+ compile-with "${LINUXKPI_C}"
+compat/linuxkpi/common/src/linux_simple_attr.c optional compat_linuxkpi | lindebugfs \
compile-with "${LINUXKPI_C}"
-
compat/lindebugfs/lindebugfs.c optional lindebugfs \
compile-with "${LINUXKPI_C}"
diff --git a/sys/modules/linuxkpi/Makefile b/sys/modules/linuxkpi/Makefile
--- a/sys/modules/linuxkpi/Makefile
+++ b/sys/modules/linuxkpi/Makefile
@@ -22,10 +22,11 @@
linux_pci.c \
linux_radix.c \
linux_rcu.c \
- linux_seq_file.c \
linux_schedule.c \
+ linux_seq_file.c \
linux_shmemfs.c \
linux_shrinker.c \
+ linux_simple_attr.c \
linux_skbuff.c \
linux_slab.c \
linux_tasklet.c \
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 11, 1:25 PM (13 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25163274
Default Alt Text
D35883.id108583.diff (19 KB)
Attached To
Mode
D35883: LinuxKPI drm-kmod debugfs support
Attached
Detach File
Event Timeline
Log In to Comment