lkml.org 
[lkml]   [2009]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 37/53] seq_file: move traverse so it can be used from seq_read
    2.6.28-stable review patch.  If anyone has any objections, please let us know.
    ------------------

    From: Eric Biederman <ebiederm@xmission.com>

    commit 33da8892a2f9e7d4b2d9a35fc80833ba2d2b1aa6 upstream.

    In 2.6.25 some /proc files were converted to use the seq_file
    infrastructure. But seq_files do not correctly support pread(), which
    broke some usersapce applications.

    To handle pread correctly we can't assume that f_pos is where we left it
    in seq_read. So move traverse() so that we can eventually use it in
    seq_read and do thus some day support pread().

    Signed-off-by: Eric Biederman <ebiederm@xmission.com>
    Cc: Paul Turner <pjt@google.com>
    Cc: Alexey Dobriyan <adobriyan@gmail.com>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    fs/seq_file.c | 114 +++++++++++++++++++++++++++++-----------------------------
    1 file changed, 57 insertions(+), 57 deletions(-)

    --- a/fs/seq_file.c
    +++ b/fs/seq_file.c
    @@ -54,6 +54,63 @@ int seq_open(struct file *file, const st
    }
    EXPORT_SYMBOL(seq_open);

    +static int traverse(struct seq_file *m, loff_t offset)
    +{
    + loff_t pos = 0, index;
    + int error = 0;
    + void *p;
    +
    + m->version = 0;
    + index = 0;
    + m->count = m->from = 0;
    + if (!offset) {
    + m->index = index;
    + return 0;
    + }
    + if (!m->buf) {
    + m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
    + if (!m->buf)
    + return -ENOMEM;
    + }
    + p = m->op->start(m, &index);
    + while (p) {
    + error = PTR_ERR(p);
    + if (IS_ERR(p))
    + break;
    + error = m->op->show(m, p);
    + if (error < 0)
    + break;
    + if (unlikely(error)) {
    + error = 0;
    + m->count = 0;
    + }
    + if (m->count == m->size)
    + goto Eoverflow;
    + if (pos + m->count > offset) {
    + m->from = offset - pos;
    + m->count -= m->from;
    + m->index = index;
    + break;
    + }
    + pos += m->count;
    + m->count = 0;
    + if (pos == offset) {
    + index++;
    + m->index = index;
    + break;
    + }
    + p = m->op->next(m, p, &index);
    + }
    + m->op->stop(m, p);
    + return error;
    +
    +Eoverflow:
    + m->op->stop(m, p);
    + kfree(m->buf);
    + m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
    + return !m->buf ? -ENOMEM : -EAGAIN;
    +}
    +
    /**
    * seq_read - ->read() method for sequential files.
    * @file: the file to read from
    @@ -186,63 +243,6 @@ Efault:
    }
    EXPORT_SYMBOL(seq_read);

    -static int traverse(struct seq_file *m, loff_t offset)
    -{
    - loff_t pos = 0, index;
    - int error = 0;
    - void *p;
    -
    - m->version = 0;
    - index = 0;
    - m->count = m->from = 0;
    - if (!offset) {
    - m->index = index;
    - return 0;
    - }
    - if (!m->buf) {
    - m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
    - if (!m->buf)
    - return -ENOMEM;
    - }
    - p = m->op->start(m, &index);
    - while (p) {
    - error = PTR_ERR(p);
    - if (IS_ERR(p))
    - break;
    - error = m->op->show(m, p);
    - if (error < 0)
    - break;
    - if (unlikely(error)) {
    - error = 0;
    - m->count = 0;
    - }
    - if (m->count == m->size)
    - goto Eoverflow;
    - if (pos + m->count > offset) {
    - m->from = offset - pos;
    - m->count -= m->from;
    - m->index = index;
    - break;
    - }
    - pos += m->count;
    - m->count = 0;
    - if (pos == offset) {
    - index++;
    - m->index = index;
    - break;
    - }
    - p = m->op->next(m, p, &index);
    - }
    - m->op->stop(m, p);
    - return error;
    -
    -Eoverflow:
    - m->op->stop(m, p);
    - kfree(m->buf);
    - m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
    - return !m->buf ? -ENOMEM : -EAGAIN;
    -}
    -
    /**
    * seq_lseek - ->llseek() method for sequential files.
    * @file: the file in question


    \
     
     \ /
      Last update: 2009-02-10 20:21    [W:0.027 / U:30.260 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site