Page MenuHomeFreeBSD

D55899.id173816.diff
No OneTemporary

D55899.id173816.diff

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,53 @@
struct seq_file *m;
struct sbuf *sbuf;
void *p;
- ssize_t rc;
+ off_t dummy_pos;
+ ssize_t rc, nread;
m = f->private_data;
sbuf = m->buf;
sbuf_clear(sbuf);
p = m->op->start(m, ppos);
- rc = m->op->show(m, p);
- if (rc)
- return (rc);
+ nread = 0;
+ while (size > 0) {
+ rc = m->op->show(m, p);
+ if (rc != 0)
+ break;
- rc = sbuf_finish(sbuf);
- if (rc)
- return (rc);
+ rc = sbuf_finish(sbuf);
+ if (rc != 0) {
+ rc = -rc;
+ break;
+ }
- return (simple_read_from_buffer(ubuf, size, ppos, sbuf_data(sbuf),
- sbuf_len(sbuf)));
+ /*
+ * ppos isn't an offset into this sbuf's buffer, it is
+ * instead a logical offset into the seq_file updated
+ * by the next callback. This just needs to copy out
+ * the data from the sbuf into the user buffer.
+ */
+ dummy_pos = 0;
+ rc = simple_read_from_buffer(ubuf, size, &dummy_pos,
+ sbuf_data(sbuf), sbuf_len(sbuf));
+ if (rc <= 0)
+ break;
+
+ nread += rc;
+ ubuf += rc;
+ size -= rc;
+
+ /*
+ * 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);
+ }
+ m->op->stop(m, p);
+ if (nread > 0)
+ return (nread);
+ return (rc);
}
int

File Metadata

Mime Type
text/plain
Expires
Wed, May 27, 10:27 AM (6 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29919090
Default Alt Text
D55899.id173816.diff (1 KB)

Event Timeline