fs: allocate structure unconditionally in seq_open()
authorYann Droneaud <ydroneaud@opteya.com>
Tue, 30 Jun 2015 21:57:33 +0000 (14:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Jul 2015 02:44:57 +0000 (19:44 -0700)
Since patch described below, from v2.6.15-rc1, seq_open() could use a
struct seq_file already allocated by the caller if the pointer to the
structure is stored in file->private_data before calling the function.

    Commit 1abe77b0fc4b485927f1f798ae81a752677e1d05
    Author: Al Viro <viro@zeniv.linux.org.uk>
    Date:   Mon Nov 7 17:15:34 2005 -0500

        [PATCH] allow callers of seq_open do allocation themselves

        Allow caller of seq_open() to kmalloc() seq_file + whatever else they
        want and set ->private_data to it.  seq_open() will then abstain from
        doing allocation itself.

As there's no more use for such feature, as it could be easily replaced by
calls to seq_open_private() (see commit 39699037a5c9 ("[FS] seq_file:
Introduce the seq_open_private()")) and seq_release_private() (see
v2.6.0-test3), support for this uncommon feature can be removed from
seq_open().

Link: http://lkml.kernel.org/r/cover.1433193673.git.ydroneaud@opteya.com
Signed-off-by: Yann Droneaud <ydroneaud@opteya.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>
fs/seq_file.c

index 555f82155be80d4e27eb62785af0926093de6b04..5f163c6c821cb3c5d4b0153ae1dbad7a129deb80 100644 (file)
@@ -51,15 +51,16 @@ static void *seq_buf_alloc(unsigned long size)
  */
 int seq_open(struct file *file, const struct seq_operations *op)
 {
-       struct seq_file *p = file->private_data;
+       struct seq_file *p;
+
+       WARN_ON(file->private_data);
+
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       file->private_data = p;
 
-       if (!p) {
-               p = kmalloc(sizeof(*p), GFP_KERNEL);
-               if (!p)
-                       return -ENOMEM;
-               file->private_data = p;
-       }
-       memset(p, 0, sizeof(*p));
        mutex_init(&p->lock);
        p->op = op;
 #ifdef CONFIG_USER_NS