lkml.org 
[lkml]   [2007]   [Aug]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 1/2] Seq_file add support for sorted list
    Add support for sorted list in seq_file. It aims at changing the way
    /proc/modules and kallsyms iterates on the module list to remove a race between
    module unload and module/symbol listing.

    The list is sorted by ascending list_head pointer address.

    Changelog:

    When reading the data by small chunks (i.e. byte by byte), the index (ppos) is
    incremented by seq_read() directly and no "next" callback is called when going
    to the next module.

    Therefore, use ppos instead of m->private to deal with the fact that this index
    is incremented directly to pass to the next module in seq_read() after the
    buffer has been emptied.

    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
    ---
    fs/seq_file.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
    include/linux/seq_file.h | 20 ++++++++++++++++++++
    2 files changed, 67 insertions(+)

    Index: linux-2.6-lttng/fs/seq_file.c
    ===================================================================
    --- linux-2.6-lttng.orig/fs/seq_file.c 2007-08-25 14:39:03.000000000 -0400
    +++ linux-2.6-lttng/fs/seq_file.c 2007-08-27 11:11:33.000000000 -0400
    @@ -510,3 +510,50 @@ struct list_head *seq_list_next(void *v,
    }

    EXPORT_SYMBOL(seq_list_next);
    +
    +struct list_head *seq_sorted_list_start(struct list_head *head, loff_t *ppos)
    +{
    + struct list_head *lh;
    +
    + list_for_each(lh, head)
    + if ((unsigned long)lh >= *ppos) {
    + *ppos = (unsigned long)lh;
    + return lh;
    + }
    + return NULL;
    +}
    +
    +EXPORT_SYMBOL(seq_sorted_list_start);
    +
    +struct list_head *seq_sorted_list_start_head(struct list_head *head,
    + loff_t *ppos)
    +{
    + struct list_head *lh;
    +
    + if (!*ppos) {
    + *ppos = (unsigned long)head;
    + return head;
    + }
    + list_for_each(lh, head)
    + if ((unsigned long)lh >= *ppos) {
    + *ppos = (long)lh->prev;
    + return lh->prev;
    + }
    + return NULL;
    +}
    +
    +EXPORT_SYMBOL(seq_sorted_list_start_head);
    +
    +struct list_head *seq_sorted_list_next(void *p, struct list_head *head,
    + loff_t *ppos)
    +{
    + struct list_head *lh;
    + void *next;
    +
    + lh = ((struct list_head *)p)->next;
    + next = (lh == head) ? NULL : lh;
    + *ppos = next ? (unsigned long)next : -1UL;
    + return next;
    +}
    +
    +EXPORT_SYMBOL(seq_sorted_list_next);
    Index: linux-2.6-lttng/include/linux/seq_file.h
    ===================================================================
    --- linux-2.6-lttng.orig/include/linux/seq_file.h 2007-08-25 14:39:03.000000000 -0400
    +++ linux-2.6-lttng/include/linux/seq_file.h 2007-08-27 11:11:33.000000000 -0400
    @@ -63,5 +63,25 @@ extern struct list_head *seq_list_start_
    extern struct list_head *seq_list_next(void *v, struct list_head *head,
    loff_t *ppos);

    +/*
    + * Helpers for iteration over a list sorted by ascending head pointer address.
    + * To be used in contexts where preemption cannot be disabled to insure to
    + * continue iteration on a modified list starting at the same location where it
    + * stopped, or at a following location. It insures that the lost information
    + * will only be in elements added/removed from the list between iterations.
    + * void *pos is only used to get the next list element and may not be a valid
    + * list_head anymore when given to seq_sorted_list_start() or
    + * seq_sorted_list_start_head().
    + */
    +extern struct list_head *seq_sorted_list_start(struct list_head *head,
    + loff_t *ppos);
    +extern struct list_head *seq_sorted_list_start_head(struct list_head *head,
    + loff_t *ppos);
    +/*
    + * next must be called with an existing p node
    + */
    +extern struct list_head *seq_sorted_list_next(void *p, struct list_head *head,
    + loff_t *ppos);
    +
    #endif
    #endif
    --
    Mathieu Desnoyers
    Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
    OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-08-27 18:29    [W:0.026 / U:0.204 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site