lkml.org 
[lkml]   [2013]   [Nov]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 19/39] sysfs, kernfs: add kernfs_ops->seq_{start|next|stop}()
    Date
    kernfs_ops currently only supports single_open() behavior which is
    pretty restrictive. Add optional callbacks ->seq_{start|next|stop}()
    which, when implemented, are invoked for seq_file traversal. This
    allows full seq_file functionality for kernfs users. This currently
    doesn't have any user and doesn't change any behavior.

    v2: Refreshed on top of the updated "sysfs, kernfs: prepare read path
    for kernfs".

    Signed-off-by: Tejun Heo <tj@kernel.org>
    ---
    fs/sysfs/file.c | 39 ++++++++++++++++++++++++++++-----------
    include/linux/kernfs.h | 9 +++++++--
    2 files changed, 35 insertions(+), 13 deletions(-)

    diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
    index 1317dab..3d50f11 100644
    --- a/fs/sysfs/file.c
    +++ b/fs/sysfs/file.c
    @@ -146,6 +146,7 @@ static ssize_t sysfs_kf_bin_read(struct sysfs_open_file *of, char *buf,
    static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos)
    {
    struct sysfs_open_file *of = sf->private;
    + const struct kernfs_ops *ops;

    /*
    * @of->mutex nests outside active ref and is just to ensure that
    @@ -155,26 +156,42 @@ static void *kernfs_seq_start(struct seq_file *sf, loff_t *ppos)
    if (!sysfs_get_active(of->sd))
    return ERR_PTR(-ENODEV);

    - /*
    - * The same behavior and code as single_open(). Returns !NULL if
    - * pos is at the beginning; otherwise, NULL.
    - */
    - return NULL + !*ppos;
    + ops = kernfs_ops(of->sd);
    + if (ops->seq_start) {
    + return ops->seq_start(sf, ppos);
    + } else {
    + /*
    + * The same behavior and code as single_open(). Returns
    + * !NULL if pos is at the beginning; otherwise, NULL.
    + */
    + return NULL + !*ppos;
    + }
    }

    static void *kernfs_seq_next(struct seq_file *sf, void *v, loff_t *ppos)
    {
    - /*
    - * The same behavior and code as single_open(), always terminate
    - * after the initial read.
    - */
    - ++*ppos;
    - return NULL;
    + struct sysfs_open_file *of = sf->private;
    + const struct kernfs_ops *ops = kernfs_ops(of->sd);
    +
    + if (ops->seq_next) {
    + return ops->seq_next(sf, v, ppos);
    + } else {
    + /*
    + * The same behavior and code as single_open(), always
    + * terminate after the initial read.
    + */
    + ++*ppos;
    + return NULL;
    + }
    }

    static void kernfs_seq_stop(struct seq_file *sf, void *v)
    {
    struct sysfs_open_file *of = sf->private;
    + const struct kernfs_ops *ops = kernfs_ops(of->sd);
    +
    + if (ops->seq_stop)
    + ops->seq_stop(sf, v);

    sysfs_put_active(of->sd);
    mutex_unlock(&of->mutex);
    diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
    index 869a0a7..d93c5ef 100644
    --- a/include/linux/kernfs.h
    +++ b/include/linux/kernfs.h
    @@ -37,8 +37,9 @@ struct kernfs_ops {
    /*
    * Read is handled by either seq_file or raw_read().
    *
    - * If seq_show() is present, seq_file path is active. The behavior
    - * is equivalent to single_open(). @sf->private points to the
    + * If seq_show() is present, seq_file path is active. Other seq
    + * operations are optional and if not implemented, the behavior is
    + * equivalent to single_open(). @sf->private points to the
    * associated sysfs_open_file.
    *
    * read() is bounced through kernel buffer and a read larger than
    @@ -46,6 +47,10 @@ struct kernfs_ops {
    */
    int (*seq_show)(struct seq_file *sf, void *v);

    + void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
    + void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
    + void (*seq_stop)(struct seq_file *sf, void *v);
    +
    ssize_t (*read)(struct sysfs_open_file *of, char *buf, size_t bytes,
    loff_t off);

    --
    1.8.3.1


    \
     
     \ /
      Last update: 2013-11-03 11:21    [W:4.169 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site