Re: [Linux-kernel] [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-07 Thread Rob Jones



On 07/08/14 15:22, Steven Whitehouse wrote:

Hi,

On 07/08/14 15:16, Rob Jones wrote:



On 07/08/14 15:09, Rob Jones wrote:

Hi Steve,

On 07/08/14 14:32, Steven Whitehouse wrote:

Hi,

On 07/08/14 13:58, Rob Jones wrote:
[snip]


On a related subject, Having looked at a few uses of seq_file, I must
say that some users seem to make assumptions about the internal
workings of the module. Dangerous behaviour as only some behaviours
are
documented.

e.g. The behaviour that "struct seq_file" pointer is stored in
file->private_data is documented and can therefore be relied upon but
the fact that the output buffer and its size are only defined at the
first output (and can therefore be pre-defined and pre-allocated by
user code) is not documented and could therefore change without
warning.

This second behaviour is assumed in, for example, module
fs/gfs2/glock.c
which could, therefore, stop working properly without warning if the
internal behaviour was changed.


While it is undocumented, it is I understand, how this feature was
intended to be used, so I think that it is safe to do this in the GFS2
case. Here is a ref to the thread which explains how it landed up like
that:
https://www.redhat.com/archives/cluster-devel/2012-June/msg0.html


No criticism was intended of that particular piece of code, It has been
there for a couple of years and is, presumably, still working :-)

It was just a general point about things needing to be written down. A
behaviour such as you were relying on can be a very positive thing but
it would be of much greater use if it was written down in the file docs.

I completely missed seq_file_private() because I was looking at the


Sorry, that should be seq_open_private()

Why does one never see the mistake until *after* hitting send?


Always the way, unfortunately!


docs more than the code. If it had been written down in the docs it
would have saved me quite a bit of time, similarly, if the buffer
allocation behaviour was documented, changes to seq_file.c would not be
made that could break your code.

God knows, I'm not a fan of unnecessary documentation but where it's
useful I'm all for it.


Yes, very much agreed, and no doubt it would be useful in this case. I
hoped that the earlier thread might be a useful starting point, since it
explained some of the whys and wherefores,


Well, I'm making a start by documenting seq_open_private(). Small
steps :-)



Steve.





--
Rob Jones
Codethink Ltd
mailto:rob.jo...@codethink.co.uk
tel:+44 161 236 5575
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-kernel] [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-07 Thread Steven Whitehouse

Hi,

On 07/08/14 15:16, Rob Jones wrote:



On 07/08/14 15:09, Rob Jones wrote:

Hi Steve,

On 07/08/14 14:32, Steven Whitehouse wrote:

Hi,

On 07/08/14 13:58, Rob Jones wrote:
[snip]


On a related subject, Having looked at a few uses of seq_file, I must
say that some users seem to make assumptions about the internal
workings of the module. Dangerous behaviour as only some behaviours 
are

documented.

e.g. The behaviour that "struct seq_file" pointer is stored in
file->private_data is documented and can therefore be relied upon but
the fact that the output buffer and its size are only defined at the
first output (and can therefore be pre-defined and pre-allocated by
user code) is not documented and could therefore change without 
warning.


This second behaviour is assumed in, for example, module 
fs/gfs2/glock.c

which could, therefore, stop working properly without warning if the
internal behaviour was changed.


While it is undocumented, it is I understand, how this feature was
intended to be used, so I think that it is safe to do this in the GFS2
case. Here is a ref to the thread which explains how it landed up like
that:
https://www.redhat.com/archives/cluster-devel/2012-June/msg0.html


No criticism was intended of that particular piece of code, It has been
there for a couple of years and is, presumably, still working :-)

It was just a general point about things needing to be written down. A
behaviour such as you were relying on can be a very positive thing but
it would be of much greater use if it was written down in the file docs.

I completely missed seq_file_private() because I was looking at the


Sorry, that should be seq_open_private()

Why does one never see the mistake until *after* hitting send?


Always the way, unfortunately!


docs more than the code. If it had been written down in the docs it
would have saved me quite a bit of time, similarly, if the buffer
allocation behaviour was documented, changes to seq_file.c would not be
made that could break your code.

God knows, I'm not a fan of unnecessary documentation but where it's
useful I'm all for it.

Yes, very much agreed, and no doubt it would be useful in this case. I 
hoped that the earlier thread might be a useful starting point, since it 
explained some of the whys and wherefores,


Steve.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Linux-kernel] [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-07 Thread Rob Jones



On 07/08/14 15:09, Rob Jones wrote:

Hi Steve,

On 07/08/14 14:32, Steven Whitehouse wrote:

Hi,

On 07/08/14 13:58, Rob Jones wrote:
[snip]


On a related subject, Having looked at a few uses of seq_file, I must
say that some users seem to make assumptions about the internal
workings of the module. Dangerous behaviour as only some behaviours are
documented.

e.g. The behaviour that "struct seq_file" pointer is stored in
file->private_data is documented and can therefore be relied upon but
the fact that the output buffer and its size are only defined at the
first output (and can therefore be pre-defined and pre-allocated by
user code) is not documented and could therefore change without warning.

This second behaviour is assumed in, for example, module fs/gfs2/glock.c
which could, therefore, stop working properly without warning if the
internal behaviour was changed.


While it is undocumented, it is I understand, how this feature was
intended to be used, so I think that it is safe to do this in the GFS2
case. Here is a ref to the thread which explains how it landed up like
that:
https://www.redhat.com/archives/cluster-devel/2012-June/msg0.html


No criticism was intended of that particular piece of code, It has been
there for a couple of years and is, presumably, still working :-)

It was just a general point about things needing to be written down. A
behaviour such as you were relying on can be a very positive thing but
it would be of much greater use if it was written down in the file docs.

I completely missed seq_file_private() because I was looking at the


Sorry, that should be seq_open_private()

Why does one never see the mistake until *after* hitting send?


docs more than the code. If it had been written down in the docs it
would have saved me quite a bit of time, similarly, if the buffer
allocation behaviour was documented, changes to seq_file.c would not be
made that could break your code.

God knows, I'm not a fan of unnecessary documentation but where it's
useful I'm all for it.



Steve.




--
Rob Jones
Codethink Ltd
mailto:rob.jo...@codethink.co.uk
tel:+44 161 236 5575
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-07 Thread Rob Jones

Hi Steve,

On 07/08/14 14:32, Steven Whitehouse wrote:

Hi,

On 07/08/14 13:58, Rob Jones wrote:
[snip]


On a related subject, Having looked at a few uses of seq_file, I must
say that some users seem to make assumptions about the internal
workings of the module. Dangerous behaviour as only some behaviours are
documented.

e.g. The behaviour that "struct seq_file" pointer is stored in
file->private_data is documented and can therefore be relied upon but
the fact that the output buffer and its size are only defined at the
first output (and can therefore be pre-defined and pre-allocated by
user code) is not documented and could therefore change without warning.

This second behaviour is assumed in, for example, module fs/gfs2/glock.c
which could, therefore, stop working properly without warning if the
internal behaviour was changed.


While it is undocumented, it is I understand, how this feature was
intended to be used, so I think that it is safe to do this in the GFS2
case. Here is a ref to the thread which explains how it landed up like
that:
https://www.redhat.com/archives/cluster-devel/2012-June/msg0.html


No criticism was intended of that particular piece of code, It has been
there for a couple of years and is, presumably, still working :-)

It was just a general point about things needing to be written down. A
behaviour such as you were relying on can be a very positive thing but
it would be of much greater use if it was written down in the file docs.

I completely missed seq_file_private() because I was looking at the
docs more than the code. If it had been written down in the docs it
would have saved me quite a bit of time, similarly, if the buffer
allocation behaviour was documented, changes to seq_file.c would not be
made that could break your code.

God knows, I'm not a fan of unnecessary documentation but where it's
useful I'm all for it.



Steve.


--
Rob Jones
Codethink Ltd
mailto:rob.jo...@codethink.co.uk
tel:+44 161 236 5575
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-07 Thread Steven Whitehouse

Hi,

On 07/08/14 13:58, Rob Jones wrote:
[snip]


On a related subject, Having looked at a few uses of seq_file, I must
say that some users seem to make assumptions about the internal
workings of the module. Dangerous behaviour as only some behaviours are
documented.

e.g. The behaviour that "struct seq_file" pointer is stored in
file->private_data is documented and can therefore be relied upon but
the fact that the output buffer and its size are only defined at the
first output (and can therefore be pre-defined and pre-allocated by
user code) is not documented and could therefore change without warning.

This second behaviour is assumed in, for example, module fs/gfs2/glock.c
which could, therefore, stop working properly without warning if the
internal behaviour was changed.

While it is undocumented, it is I understand, how this feature was 
intended to be used, so I think that it is safe to do this in the GFS2 
case. Here is a ref to the thread which explains how it landed up like that:

https://www.redhat.com/archives/cluster-devel/2012-June/msg0.html

Steve.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-07 Thread Rob Jones



On 06/08/14 20:14, Eric W. Biederman wrote:

Rob Jones  writes:


On 06/08/14 17:02, Al Viro wrote:

On Tue, Jul 29, 2014 at 06:39:53PM +0100, Rob Jones wrote:


At the moment these consumers have to obtain the struct seq_file pointer
(stored by seq_open() in file->private_data) and then store a pointer to
their own data in the private field of the struct seq_file so that it
can be accessed by the iterator functions.

Although this is not a long piece of code it is unneccessary boilerplate.


How many of those do we actually have?


A quick grep (I didn't examine them all) showed what looked like at
least 80 instances of the work around.


I took a quick look as well and what I saw was that if we were to
implement the helpers: seq_open_PDE_DATA, and seq_open_i_private.  That
would cover essentially all of seq_open that set seq_file->private.  So
my gut feel is that a seq_open_priv is the wrong helper.

In the vast majority of the cases either seq_open is good enough,
we want seq_open_private, or seq_file->private is set to PDE_DATA
or i_private.


I completely missed seq_open_private().

Maybe because it is completely undocumented.

Having partial documentation can be worse than having no documentation
at all - if there had been no documentation I would have been obliged to
search through the code. Unfortunately, this is both tiresome and time
consuming and, given that there is a documentation file, should not be
necessary.

On a related subject, Having looked at a few uses of seq_file, I must
say that some users seem to make assumptions about the internal
workings of the module. Dangerous behaviour as only some behaviours are
documented.

e.g. The behaviour that "struct seq_file" pointer is stored in
file->private_data is documented and can therefore be relied upon but
the fact that the output buffer and its size are only defined at the
first output (and can therefore be pre-defined and pre-allocated by
user code) is not documented and could therefore change without warning.

This second behaviour is assumed in, for example, module fs/gfs2/glock.c
which could, therefore, stop working properly without warning if the
internal behaviour was changed.



I think there may be 5 cases in the kernel that do something different,
and those cases probably need a code audit.


seq_open() remains in place and its behaviour remains unchanged so no
existing code should be broken by this patch.


I have no objections against such helper, but I's rather have it
implemented via seq_open() (and as a static inline, not an export),
not the other way round.  Oh, and conversion of at least some users would
be nice to have as well...


I have no significant objection but having both seq_open_private
and seq_open_priv seems confusing name wise.


Rather than pursuing my original patch, I think I will document
seq_open_private() as it achieves the same objective in a slightly
different way. Had I found it initially I almost certainly wouldn't
have created the patch.



Eric


--
Rob Jones
Codethink Ltd
mailto:rob.jo...@codethink.co.uk
tel:+44 161 236 5575
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-06 Thread Eric W. Biederman
Al Viro  writes:

> On Wed, Aug 06, 2014 at 05:16:49PM +0100, Rob Jones wrote:
>
>> I'm not quite sure I understand your meaning when you say "via seq_open"
>> though, that function call format needs to stay the same or lots of
>> code will break, so I can't just add the third parameter on the end.
>> (C++ does have *some* advantages!) Can you clarify, please?
>
> seq_open_private() can be implemented as call of seq_open() +
> assignment...

This is why I object to the name seq_open_priv() for the new code.
seq_open_private() is already implemented and base on seq_open().

And the names are close enough together it is confusing :(

Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-06 Thread Al Viro
On Wed, Aug 06, 2014 at 05:16:49PM +0100, Rob Jones wrote:

> I'm not quite sure I understand your meaning when you say "via seq_open"
> though, that function call format needs to stay the same or lots of
> code will break, so I can't just add the third parameter on the end.
> (C++ does have *some* advantages!) Can you clarify, please?

seq_open_private() can be implemented as call of seq_open() + assignment...
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-06 Thread Eric W. Biederman
Rob Jones  writes:

> On 06/08/14 17:02, Al Viro wrote:
>> On Tue, Jul 29, 2014 at 06:39:53PM +0100, Rob Jones wrote:
>>
>>> At the moment these consumers have to obtain the struct seq_file pointer
>>> (stored by seq_open() in file->private_data) and then store a pointer to
>>> their own data in the private field of the struct seq_file so that it
>>> can be accessed by the iterator functions.
>>>
>>> Although this is not a long piece of code it is unneccessary boilerplate.
>>
>> How many of those do we actually have?
>
> A quick grep (I didn't examine them all) showed what looked like at
> least 80 instances of the work around.

I took a quick look as well and what I saw was that if we were to
implement the helpers: seq_open_PDE_DATA, and seq_open_i_private.  That
would cover essentially all of seq_open that set seq_file->private.  So
my gut feel is that a seq_open_priv is the wrong helper.

In the vast majority of the cases either seq_open is good enough,
we want seq_open_private, or seq_file->private is set to PDE_DATA
or i_private.

I think there may be 5 cases in the kernel that do something different,
and those cases probably need a code audit.

>>> seq_open() remains in place and its behaviour remains unchanged so no
>>> existing code should be broken by this patch.
>>
>> I have no objections against such helper, but I's rather have it
>> implemented via seq_open() (and as a static inline, not an export),
>> not the other way round.  Oh, and conversion of at least some users would
>> be nice to have as well...

I have no significant objection but having both seq_open_private
and seq_open_priv seems confusing name wise.

Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-06 Thread Rob Jones

On 06/08/14 17:02, Al Viro wrote:

On Tue, Jul 29, 2014 at 06:39:53PM +0100, Rob Jones wrote:


At the moment these consumers have to obtain the struct seq_file pointer
(stored by seq_open() in file->private_data) and then store a pointer to
their own data in the private field of the struct seq_file so that it
can be accessed by the iterator functions.

Although this is not a long piece of code it is unneccessary boilerplate.


How many of those do we actually have?


A quick grep (I didn't examine them all) showed what looked like at
least 80 instances of the work around.




seq_open() remains in place and its behaviour remains unchanged so no
existing code should be broken by this patch.


I have no objections against such helper, but I's rather have it
implemented via seq_open() (and as a static inline, not an export),
not the other way round.  Oh, and conversion of at least some users would
be nice to have as well...




I did wonder about doing it as an inline but would argue that, for
efficiency, an external is better. There are some hundreds of calls to
seq_open(), each of which would need the compiler to insert the NULL
parameter, that seems like quite a few bytes of code added to the kernel
for the sake of saving one symbol export. However, if I'm wrong, I'll
happily change it to an inline, you guys have much more kernel
experience than me.

I'm not quite sure I understand your meaning when you say "via seq_open"
though, that function call format needs to stay the same or lots of
code will break, so I can't just add the third parameter on the end.
(C++ does have *some* advantages!) Can you clarify, please?

I was planning on changing a bunch of the instances after the patch went 
in. I can easily add a sample tidy up or two to the end, there's no

shortage of candidates.

--
Rob Jones
Codethink Ltd
mailto:rob.jo...@codethink.co.uk
tel:+44 161 236 5575
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-06 Thread Al Viro
On Tue, Jul 29, 2014 at 06:39:53PM +0100, Rob Jones wrote:

> At the moment these consumers have to obtain the struct seq_file pointer
> (stored by seq_open() in file->private_data) and then store a pointer to
> their own data in the private field of the struct seq_file so that it
> can be accessed by the iterator functions.
> 
> Although this is not a long piece of code it is unneccessary boilerplate.

How many of those do we actually have?

> seq_open() remains in place and its behaviour remains unchanged so no
> existing code should be broken by this patch.

I have no objections against such helper, but I's rather have it
implemented via seq_open() (and as a static inline, not an export),
not the other way round.  Oh, and conversion of at least some users would
be nice to have as well...
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] seq_file: Allow private data to be supplied on seq_open

2014-08-06 Thread Rob Jones

Does anyone have any feedback on this?

I would have thought it was quite uncontroversial.

On 29/07/14 18:39, Rob Jones wrote:

Create a function seq_open_priv() that is identical to seq_open() except
that it accepts a void * parameter that it stores in the private field
of the struct seq_file.

Document seq_open_priv().

Some consumers of the seq_file interface need to pass data to their
iterators that is best obtained at the time the seq_file is opened.

At the moment these consumers have to obtain the struct seq_file pointer
(stored by seq_open() in file->private_data) and then store a pointer to
their own data in the private field of the struct seq_file so that it
can be accessed by the iterator functions.

Although this is not a long piece of code it is unneccessary boilerplate.

seq_open() remains in place and its behaviour remains unchanged so no
existing code should be broken by this patch.

Signed-off-by: Ian Molton 
Signed-off-by: Rob Jones 
---
  Documentation/filesystems/seq_file.txt |9 +
  fs/seq_file.c  |   30 --
  include/linux/seq_file.h   |1 +
  3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/Documentation/filesystems/seq_file.txt 
b/Documentation/filesystems/seq_file.txt
index a1e2e0d..128ffee 100644
--- a/Documentation/filesystems/seq_file.txt
+++ b/Documentation/filesystems/seq_file.txt
@@ -226,6 +226,15 @@ be used for more than one file, you can store an arbitrary 
pointer in the
  private field of the seq_file structure; that value can then be retrieved
  by the iterator functions.

+There is also a function seq_open_priv() which behaves identically to
+seq_open() except that it takes an additional void * parameter that it
+stores in the private field of the seq_file structure, thereby making it
+available to the start function and thus all subsequent iterator functions
+Note that a corresponding wrapper function for seq_release() may need to
+be created to free any resources allocated by an open function that uses
+this capability (although, for simple cases, seq_release_private() may
+suffice).
+
  The other operations of interest - read(), llseek(), and release() - are
  all implemented by the seq_file code itself. So a virtual file's
  file_operations structure will look like:
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 1d641bb..9a0db94 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -31,9 +31,10 @@ static void seq_set_overflow(struct seq_file *m)
  }

  /**
- * seq_open -  initialize sequential file
+ * seq_open_priv - initialize sequential file with private data
   *@file: file we initialize
   *@op: method table describing the sequence
+ * @d: private data to be made available to the iterator functions
   *
   *seq_open() sets @file, associating it with a sequence described
   *by @op.  @op->start() sets the iterator up and returns the first
@@ -43,8 +44,12 @@ static void seq_set_overflow(struct seq_file *m)
   *ERR_PTR(error).  In the end of sequence they return %NULL. ->show()
   *returns 0 in case of success and negative number in case of error.
   *Returning SEQ_SKIP means "discard this element and move on".
+ *
+ * Supplying @d allows data that is only available at the time the file
+ * is opened to be supplied to @op->start() (and thereby to @op->next()
+ * as well).
   */
-int seq_open(struct file *file, const struct seq_operations *op)
+int seq_open_priv(struct file *file, const struct seq_operations *op, void *d)
  {
struct seq_file *p = file->private_data;

@@ -57,6 +62,7 @@ int seq_open(struct file *file, const struct seq_operations 
*op)
memset(p, 0, sizeof(*p));
mutex_init(&p->lock);
p->op = op;
+   p->private = d;
  #ifdef CONFIG_USER_NS
p->user_ns = file->f_cred->user_ns;
  #endif
@@ -80,6 +86,26 @@ int seq_open(struct file *file, const struct seq_operations 
*op)
file->f_mode &= ~FMODE_PWRITE;
return 0;
  }
+EXPORT_SYMBOL(seq_open_priv);
+
+/**
+ * seq_open -  initialize sequential file
+ * @file: file we initialize
+ * @op: method table describing the sequence
+ *
+ * seq_open() sets @file, associating it with a sequence described
+ * by @op.  @op->start() sets the iterator up and returns the first
+ * element of sequence. @op->stop() shuts it down.  @op->next()
+ * returns the next element of sequence.  @op->show() prints element
+ * into the buffer.  In case of error ->start() and ->next() return
+ * ERR_PTR(error).  In the end of sequence they return %NULL. ->show()
+ * returns 0 in case of success and negative number in case of error.
+ * Returning SEQ_SKIP means "discard this element and move on".
+ */
+int seq_open(struct file *file, const struct seq_operations *op)
+{
+   return seq_open_priv(file, op, NULL);
+}
  EXPORT_SYMBOL(seq_open);

  static int traverse(struct seq_file *m, loff_

[PATCH] seq_file: Allow private data to be supplied on seq_open

2014-07-29 Thread Rob Jones
Create a function seq_open_priv() that is identical to seq_open() except
that it accepts a void * parameter that it stores in the private field
of the struct seq_file.

Document seq_open_priv().

Some consumers of the seq_file interface need to pass data to their
iterators that is best obtained at the time the seq_file is opened.

At the moment these consumers have to obtain the struct seq_file pointer
(stored by seq_open() in file->private_data) and then store a pointer to
their own data in the private field of the struct seq_file so that it
can be accessed by the iterator functions.

Although this is not a long piece of code it is unneccessary boilerplate.

seq_open() remains in place and its behaviour remains unchanged so no
existing code should be broken by this patch.

Signed-off-by: Ian Molton 
Signed-off-by: Rob Jones 
---
 Documentation/filesystems/seq_file.txt |9 +
 fs/seq_file.c  |   30 --
 include/linux/seq_file.h   |1 +
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/Documentation/filesystems/seq_file.txt 
b/Documentation/filesystems/seq_file.txt
index a1e2e0d..128ffee 100644
--- a/Documentation/filesystems/seq_file.txt
+++ b/Documentation/filesystems/seq_file.txt
@@ -226,6 +226,15 @@ be used for more than one file, you can store an arbitrary 
pointer in the
 private field of the seq_file structure; that value can then be retrieved
 by the iterator functions.
 
+There is also a function seq_open_priv() which behaves identically to
+seq_open() except that it takes an additional void * parameter that it
+stores in the private field of the seq_file structure, thereby making it
+available to the start function and thus all subsequent iterator functions
+Note that a corresponding wrapper function for seq_release() may need to
+be created to free any resources allocated by an open function that uses
+this capability (although, for simple cases, seq_release_private() may
+suffice).
+
 The other operations of interest - read(), llseek(), and release() - are
 all implemented by the seq_file code itself. So a virtual file's
 file_operations structure will look like:
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 1d641bb..9a0db94 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -31,9 +31,10 @@ static void seq_set_overflow(struct seq_file *m)
 }
 
 /**
- * seq_open -  initialize sequential file
+ * seq_open_priv - initialize sequential file with private data
  * @file: file we initialize
  * @op: method table describing the sequence
+ * @d: private data to be made available to the iterator functions
  *
  * seq_open() sets @file, associating it with a sequence described
  * by @op.  @op->start() sets the iterator up and returns the first
@@ -43,8 +44,12 @@ static void seq_set_overflow(struct seq_file *m)
  * ERR_PTR(error).  In the end of sequence they return %NULL. ->show()
  * returns 0 in case of success and negative number in case of error.
  * Returning SEQ_SKIP means "discard this element and move on".
+ *
+ * Supplying @d allows data that is only available at the time the file
+ * is opened to be supplied to @op->start() (and thereby to @op->next()
+ * as well).
  */
-int seq_open(struct file *file, const struct seq_operations *op)
+int seq_open_priv(struct file *file, const struct seq_operations *op, void *d)
 {
struct seq_file *p = file->private_data;
 
@@ -57,6 +62,7 @@ int seq_open(struct file *file, const struct seq_operations 
*op)
memset(p, 0, sizeof(*p));
mutex_init(&p->lock);
p->op = op;
+   p->private = d;
 #ifdef CONFIG_USER_NS
p->user_ns = file->f_cred->user_ns;
 #endif
@@ -80,6 +86,26 @@ int seq_open(struct file *file, const struct seq_operations 
*op)
file->f_mode &= ~FMODE_PWRITE;
return 0;
 }
+EXPORT_SYMBOL(seq_open_priv);
+
+/**
+ * seq_open -  initialize sequential file
+ * @file: file we initialize
+ * @op: method table describing the sequence
+ *
+ * seq_open() sets @file, associating it with a sequence described
+ * by @op.  @op->start() sets the iterator up and returns the first
+ * element of sequence. @op->stop() shuts it down.  @op->next()
+ * returns the next element of sequence.  @op->show() prints element
+ * into the buffer.  In case of error ->start() and ->next() return
+ * ERR_PTR(error).  In the end of sequence they return %NULL. ->show()
+ * returns 0 in case of success and negative number in case of error.
+ * Returning SEQ_SKIP means "discard this element and move on".
+ */
+int seq_open(struct file *file, const struct seq_operations *op)
+{
+   return seq_open_priv(file, op, NULL);
+}
 EXPORT_SYMBOL(seq_open);
 
 static int traverse(struct seq_file *m, loff_t offset)
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 52e0097..fce87af 100644
--- a/include/linux/seq_file.h
+++ b/inc