diff options
| author | Tejun Heo <tj@kernel.org> | 2013-11-28 14:54:26 -0500 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-29 17:48:14 -0800 | 
| commit | d19b9846df64d8845be682b6318bd1aee246cf60 (patch) | |
| tree | 688842d196ae287bce080fe2e13ca00e796c8a06 /fs/sysfs | |
| parent | 2d0cfbec2a95c16818960fda1dfa815fd1a62070 (diff) | |
sysfs, kernfs: add kernfs_ops->seq_{start|next|stop}()
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/sysfs')
| -rw-r--r-- | fs/sysfs/file.c | 39 | 
1 files changed, 28 insertions, 11 deletions
| diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 9852450867cf..74e3478d9cb4 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); | 
