Page MenuHomeFreeBSD

D55899.diff
No OneTemporary

D55899.diff

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
@@ -39,6 +39,8 @@
#undef file
#define inode vnode
+#define SEQ_SKIP 1
+
MALLOC_DECLARE(M_LSEQ);
#define DEFINE_SHOW_ATTRIBUTE(__name) \
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
@@ -45,23 +45,73 @@
struct seq_file *m;
struct sbuf *sbuf;
void *p;
- ssize_t rc;
+ ssize_t rc, oldlen;
+ size_t todo;
m = f->private_data;
sbuf = m->buf;
sbuf_clear(sbuf);
p = m->op->start(m, ppos);
- rc = m->op->show(m, p);
- if (rc)
+ if (p == NULL)
+ return (0);
+
+ rc = 0;
+ while (size > sbuf_len(sbuf)) {
+ oldlen = sbuf_len(sbuf);
+ rc = m->op->show(m, p);
+ if (rc < 0)
+ break;
+
+ if (rc == SEQ_SKIP) {
+ /* Discard any data written in show callback. */
+ sbuf_setpos(sbuf, oldlen);
+ rc = 0;
+ }
+
+ /*
+ * If the sbuf has overflowed, bail. Discard any
+ * partial output from the show callback for this item
+ * preserving output from any earlier items. Since we
+ * break before calling the next callback to update
+ * *ppos, a subsequent read() will start by displaying
+ * the current item. However, if the current item
+ * could not be displayed by itself, still fail with
+ * ENOMEM rather than returning EOF.
+ */
+ if (sbuf_error(sbuf)) {
+ if (oldlen != 0)
+ sbuf_setpos(sbuf, oldlen);
+ break;
+ }
+
+ /*
+ * XXX: The seq_file documentation claims that Linux
+ * warns if this callback doesn't update the value in
+ * *ppos. We don't bother warning here.
+ */
+ p = m->op->next(m, p, ppos);
+ if (p == NULL)
+ break;
+ }
+ m->op->stop(m, p);
+
+ if (rc < 0)
return (rc);
rc = sbuf_finish(sbuf);
- if (rc)
- return (rc);
+ if (rc != 0)
+ return (-rc);
- return (simple_read_from_buffer(ubuf, size, ppos, sbuf_data(sbuf),
- sbuf_len(sbuf)));
+ todo = sbuf_len(sbuf);
+ if (todo > size)
+ todo = size;
+
+ rc = copyout(sbuf_data(sbuf), ubuf, todo);
+ if (rc != 0)
+ return (-rc);
+
+ return (todo);
}
int

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 22, 3:18 AM (5 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30099046
Default Alt Text
D55899.diff (2 KB)

Event Timeline