Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148933030
D55899.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D55899.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D55899: LinuxKPI: Update seq_file to properly implement the iterator interface
Attached
Detach File
Event Timeline
Log In to Comment