diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/fs/namei.c b/fs/namei.c index bcb838e2e52..385f7817bfc 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -196,6 +196,7 @@ recopy: goto error; result->uptr = filename; + result->aname = NULL; audit_getname(result); return result; @@ -209,7 +210,35 @@ getname(const char __user * filename) { return getname_flags(filename, 0, NULL); } -EXPORT_SYMBOL(getname); + +/* + * The "getname_kernel()" interface doesn't do pathnames longer + * than EMBEDDED_NAME_MAX. Deal with it - you're a kernel user. + */ +struct filename * +getname_kernel(const char * filename) +{ + struct filename *result; + char *kname; + int len; + + len = strlen(filename); + if (len >= EMBEDDED_NAME_MAX) + return ERR_PTR(-ENAMETOOLONG); + + result = __getname(); + if (unlikely(!result)) + return ERR_PTR(-ENOMEM); + + kname = (char *)result + sizeof(*result); + result->name = kname; + result->uptr = NULL; + result->aname = NULL; + result->separate = false; + + strlcpy(kname, filename, EMBEDDED_NAME_MAX); + return result; +} #ifdef CONFIG_AUDITSYSCALL void putname(struct filename *name) @@ -3927,10 +3956,13 @@ out_dput: done_path_create(&new_path, new_dentry); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); - if (!error) + if (!error) { + path_put(&old_path); goto retry; + } } if (retry_estale(error, how)) { + path_put(&old_path); how |= LOOKUP_REVAL; goto retry; } |