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 @@ -54,6 +54,7 @@ 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 @@ 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 @@ 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 @@ #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_ */ 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 @@ -79,8 +79,33 @@ 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 @@ { } -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); +}