]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/seq_file.c
tcp: Partial hint clearing has again become meaningless
[linux-2.6-omap-h63xx.git] / fs / seq_file.c
index ae59f5a6c5c1c71d704b39e42abeafdaba2d3616..bd20f7f5a93342b57a4802010c788683deb63247 100644 (file)
@@ -108,9 +108,9 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
                        goto Done;
        }
        /* we need at least one record in buffer */
+       pos = m->index;
+       p = m->op->start(m, &pos);
        while (1) {
-               pos = m->index;
-               p = m->op->start(m, &pos);
                err = PTR_ERR(p);
                if (!p || IS_ERR(p))
                        break;
@@ -119,6 +119,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
                        break;
                if (unlikely(err))
                        m->count = 0;
+               if (unlikely(!m->count)) {
+                       p = m->op->next(m, p, &pos);
+                       m->index = pos;
+                       continue;
+               }
                if (m->count < m->size)
                        goto Fill;
                m->op->stop(m, p);
@@ -128,6 +133,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
                        goto Enomem;
                m->count = 0;
                m->version = 0;
+               pos = m->index;
+               p = m->op->start(m, &pos);
        }
        m->op->stop(m, p);
        m->count = 0;
@@ -392,6 +399,36 @@ int seq_path(struct seq_file *m, struct path *path, char *esc)
 }
 EXPORT_SYMBOL(seq_path);
 
+/*
+ * Same as seq_path, but relative to supplied root.
+ *
+ * root may be changed, see __d_path().
+ */
+int seq_path_root(struct seq_file *m, struct path *path, struct path *root,
+                 char *esc)
+{
+       int err = -ENAMETOOLONG;
+       if (m->count < m->size) {
+               char *s = m->buf + m->count;
+               char *p;
+
+               spin_lock(&dcache_lock);
+               p = __d_path(path, root, s, m->size - m->count);
+               spin_unlock(&dcache_lock);
+               err = PTR_ERR(p);
+               if (!IS_ERR(p)) {
+                       s = mangle_path(s, p, esc);
+                       if (s) {
+                               p = m->buf + m->count;
+                               m->count = s - m->buf;
+                               return 0;
+                       }
+               }
+       }
+       m->count = m->size;
+       return err;
+}
+
 /*
  * returns the path of the 'dentry' from the root of its filesystem.
  */
@@ -413,6 +450,20 @@ int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc)
        return -1;
 }
 
+int seq_bitmap(struct seq_file *m, unsigned long *bits, unsigned int nr_bits)
+{
+       size_t len = bitmap_scnprintf_len(nr_bits);
+
+       if (m->count + len < m->size) {
+               bitmap_scnprintf(m->buf + m->count, m->size - m->count,
+                                bits, nr_bits);
+               m->count += len;
+               return 0;
+       }
+       m->count = m->size;
+       return -1;
+}
+
 static void *single_start(struct seq_file *p, loff_t *pos)
 {
        return NULL + (*pos == 0);