kernfs: make kernfs_walk_ns() use kernfs_pr_cont_buf[]
authorTejun Heo <tj@kernel.org>
Fri, 15 Jan 2016 17:30:14 +0000 (12:30 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Feb 2016 04:21:35 +0000 (20:21 -0800)
kernfs_walk_ns() uses a static path_buf[PATH_MAX] to separate out path
components.  Keeping around the 4k buffer just for kernfs_walk_ns() is
wasteful.  This patch makes it piggyback on kernfs_pr_cont_buf[]
instead.  This requires kernfs_walk_ns() to hold kernfs_rename_lock.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/kernfs/dir.c

index 996b7742c90b2eaf1e8b154ae3cc580293d6f94b..118d033bcbbc26a169e6e0395af4b6f9fe5e335e 100644 (file)
@@ -691,15 +691,22 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent,
                                          const unsigned char *path,
                                          const void *ns)
 {
-       static char path_buf[PATH_MAX]; /* protected by kernfs_mutex */
-       size_t len = strlcpy(path_buf, path, PATH_MAX);
-       char *p = path_buf;
-       char *name;
+       size_t len;
+       char *p, *name;
 
        lockdep_assert_held(&kernfs_mutex);
 
-       if (len >= PATH_MAX)
+       /* grab kernfs_rename_lock to piggy back on kernfs_pr_cont_buf */
+       spin_lock_irq(&kernfs_rename_lock);
+
+       len = strlcpy(kernfs_pr_cont_buf, path, sizeof(kernfs_pr_cont_buf));
+
+       if (len >= sizeof(kernfs_pr_cont_buf)) {
+               spin_unlock_irq(&kernfs_rename_lock);
                return NULL;
+       }
+
+       p = kernfs_pr_cont_buf;
 
        while ((name = strsep(&p, "/")) && parent) {
                if (*name == '\0')
@@ -707,6 +714,8 @@ static struct kernfs_node *kernfs_walk_ns(struct kernfs_node *parent,
                parent = kernfs_find_ns(parent, name, ns);
        }
 
+       spin_unlock_irq(&kernfs_rename_lock);
+
        return parent;
 }