From e56ed358afd81554e668aaa974d3f9ed201fa10d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 15 Jan 2016 12:30:14 -0500 Subject: kernfs: make kernfs_walk_ns() use kernfs_pr_cont_buf[] 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 Reported-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'fs/kernfs') diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 996b7742c90b..118d033bcbbc 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -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; } -- cgit v1.2.3