linuxkpi: Define seq_has_overflowed()
and single_open_size()
This required non-trivial changes to `linux_seq_file.c` to manage a new `(struct seq_file)->size` field. This field is read directly by DRM drivers, so we can't alias it to a call to sbuf_len(9). `single_open_size()` also depended on the ability to allocate the sbuf with a specified size instead of relying on `sbuf_new_auto()`. Reviewed by: manu Approved by: manu Differential Revision: https://reviews.freebsd.org/D39056
This commit is contained in:
parent
af0361fcc8
commit
f8c2d40227
@ -54,6 +54,7 @@ static const struct file_operations __name ## _fops = { \
|
||||
|
||||
struct seq_file {
|
||||
struct sbuf *buf;
|
||||
size_t size;
|
||||
const struct seq_operations *op;
|
||||
const struct linux_file *file;
|
||||
void *private;
|
||||
@ -68,6 +69,9 @@ struct seq_operations {
|
||||
|
||||
ssize_t seq_read(struct linux_file *, char *, size_t, off_t *);
|
||||
int seq_write(struct seq_file *seq, const void *data, size_t len);
|
||||
void seq_putc(struct seq_file *m, char c);
|
||||
void seq_puts(struct seq_file *m, const char *str);
|
||||
bool seq_has_overflowed(struct seq_file *m);
|
||||
|
||||
void *__seq_open_private(struct linux_file *, const struct seq_operations *, int);
|
||||
int seq_release_private(struct inode *, struct linux_file *);
|
||||
@ -77,6 +81,7 @@ int seq_release(struct inode *inode, struct linux_file *file);
|
||||
|
||||
off_t seq_lseek(struct linux_file *file, off_t offset, int whence);
|
||||
int single_open(struct linux_file *, int (*)(struct seq_file *, void *), void *);
|
||||
int single_open_size(struct linux_file *, int (*)(struct seq_file *, void *), void *, size_t);
|
||||
int single_release(struct inode *, struct linux_file *);
|
||||
|
||||
void lkpi_seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
|
||||
@ -85,9 +90,6 @@ void lkpi_seq_printf(struct seq_file *m, const char *fmt, ...);
|
||||
#define seq_vprintf(...) lkpi_seq_vprintf(__VA_ARGS__)
|
||||
#define seq_printf(...) lkpi_seq_printf(__VA_ARGS__)
|
||||
|
||||
#define seq_puts(m, str) sbuf_printf((m)->buf, str)
|
||||
#define seq_putc(m, str) sbuf_putc((m)->buf, str)
|
||||
|
||||
#define file linux_file
|
||||
|
||||
#endif /* _LINUXKPI_LINUX_SEQ_FILE_H_ */
|
||||
|
@ -79,8 +79,33 @@ seq_read(struct linux_file *f, char *ubuf, size_t size, off_t *ppos)
|
||||
int
|
||||
seq_write(struct seq_file *seq, const void *data, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
return (sbuf_bcpy(seq->buf, data, len));
|
||||
ret = sbuf_bcpy(seq->buf, data, len);
|
||||
if (ret == 0)
|
||||
seq->size = sbuf_len(seq->buf);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
seq_putc(struct seq_file *seq, char c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = sbuf_putc(seq->buf, c);
|
||||
if (ret == 0)
|
||||
seq->size = sbuf_len(seq->buf);
|
||||
}
|
||||
|
||||
void
|
||||
seq_puts(struct seq_file *seq, const char *str)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = sbuf_printf(seq->buf, "%s", str);
|
||||
if (ret == 0)
|
||||
seq->size = sbuf_len(seq->buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -115,21 +140,32 @@ single_stop(struct seq_file *p, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
seq_open(struct linux_file *f, const struct seq_operations *op)
|
||||
static int
|
||||
_seq_open_without_sbuf(struct linux_file *f, const struct seq_operations *op)
|
||||
{
|
||||
struct seq_file *p;
|
||||
|
||||
if ((p = malloc(sizeof(*p), M_LSEQ, M_NOWAIT|M_ZERO)) == NULL)
|
||||
return (-ENOMEM);
|
||||
|
||||
p->buf = sbuf_new_auto();
|
||||
p->file = f;
|
||||
p->op = op;
|
||||
f->private_data = (void *) p;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
seq_open(struct linux_file *f, const struct seq_operations *op)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _seq_open_without_sbuf(f, op);
|
||||
if (ret == 0)
|
||||
((struct seq_file *)f->private_data)->buf = sbuf_new_auto();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void *
|
||||
__seq_open_private(struct linux_file *f, const struct seq_operations *op, int size)
|
||||
{
|
||||
@ -153,8 +189,8 @@ __seq_open_private(struct linux_file *f, const struct seq_operations *op, int si
|
||||
return (private);
|
||||
}
|
||||
|
||||
int
|
||||
single_open(struct linux_file *f, int (*show)(struct seq_file *, void *), void *d)
|
||||
static int
|
||||
_single_open_without_sbuf(struct linux_file *f, int (*show)(struct seq_file *, void *), void *d)
|
||||
{
|
||||
struct seq_operations *op;
|
||||
int rc = -ENOMEM;
|
||||
@ -165,7 +201,7 @@ single_open(struct linux_file *f, int (*show)(struct seq_file *, void *), void *
|
||||
op->next = single_next;
|
||||
op->stop = single_stop;
|
||||
op->show = show;
|
||||
rc = seq_open(f, op);
|
||||
rc = _seq_open_without_sbuf(f, op);
|
||||
if (rc)
|
||||
free(op, M_LSEQ);
|
||||
else
|
||||
@ -174,6 +210,31 @@ single_open(struct linux_file *f, int (*show)(struct seq_file *, void *), void *
|
||||
return (rc);
|
||||
}
|
||||
|
||||
int
|
||||
single_open(struct linux_file *f, int (*show)(struct seq_file *, void *), void *d)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _single_open_without_sbuf(f, show, d);
|
||||
if (ret == 0)
|
||||
((struct seq_file *)f->private_data)->buf = sbuf_new_auto();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
single_open_size(struct linux_file *f, int (*show)(struct seq_file *, void *), void *d, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _single_open_without_sbuf(f, show, d);
|
||||
if (ret == 0)
|
||||
((struct seq_file *)f->private_data)->buf = sbuf_new(
|
||||
NULL, NULL, size, SBUF_AUTOEXTEND);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
seq_release(struct inode *inode __unused, struct linux_file *file)
|
||||
{
|
||||
@ -219,7 +280,11 @@ single_release(struct vnode *v, struct linux_file *f)
|
||||
void
|
||||
lkpi_seq_vprintf(struct seq_file *m, const char *fmt, va_list args)
|
||||
{
|
||||
sbuf_vprintf(m->buf, fmt, args);
|
||||
int ret;
|
||||
|
||||
ret = sbuf_vprintf(m->buf, fmt, args);
|
||||
if (ret == 0)
|
||||
m->size = sbuf_len(m->buf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -228,6 +293,12 @@ lkpi_seq_printf(struct seq_file *m, const char *fmt, ...)
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
seq_vprintf(m, fmt, args);
|
||||
lkpi_seq_vprintf(m, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
bool
|
||||
seq_has_overflowed(struct seq_file *m)
|
||||
{
|
||||
return (sbuf_len(m->buf) == -1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user