diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/namei.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/fs/namei.c b/fs/namei.c index 11184df3307e..e412421210cc 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2360,6 +2360,20 @@ out: | |||
2360 | return err; | 2360 | return err; |
2361 | } | 2361 | } |
2362 | 2362 | ||
2363 | static int | ||
2364 | filename_mountpoint(int dfd, struct filename *s, struct path *path, | ||
2365 | unsigned int flags) | ||
2366 | { | ||
2367 | int error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_RCU); | ||
2368 | if (unlikely(error == -ECHILD)) | ||
2369 | error = path_mountpoint(dfd, s->name, path, flags); | ||
2370 | if (unlikely(error == -ESTALE)) | ||
2371 | error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_REVAL); | ||
2372 | if (likely(!error)) | ||
2373 | audit_inode(s, path->dentry, 0); | ||
2374 | return error; | ||
2375 | } | ||
2376 | |||
2363 | /** | 2377 | /** |
2364 | * user_path_mountpoint_at - lookup a path from userland in order to umount it | 2378 | * user_path_mountpoint_at - lookup a path from userland in order to umount it |
2365 | * @dfd: directory file descriptor | 2379 | * @dfd: directory file descriptor |
@@ -2380,23 +2394,22 @@ user_path_mountpoint_at(int dfd, const char __user *name, unsigned int flags, | |||
2380 | { | 2394 | { |
2381 | struct filename *s = getname(name); | 2395 | struct filename *s = getname(name); |
2382 | int error; | 2396 | int error; |
2383 | |||
2384 | if (IS_ERR(s)) | 2397 | if (IS_ERR(s)) |
2385 | return PTR_ERR(s); | 2398 | return PTR_ERR(s); |
2386 | 2399 | error = filename_mountpoint(dfd, s, path, flags); | |
2387 | error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_RCU); | ||
2388 | if (unlikely(error == -ECHILD)) | ||
2389 | error = path_mountpoint(dfd, s->name, path, flags); | ||
2390 | if (unlikely(error == -ESTALE)) | ||
2391 | error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_REVAL); | ||
2392 | |||
2393 | if (likely(!error)) | ||
2394 | audit_inode(s, path->dentry, 0); | ||
2395 | |||
2396 | putname(s); | 2400 | putname(s); |
2397 | return error; | 2401 | return error; |
2398 | } | 2402 | } |
2399 | 2403 | ||
2404 | int | ||
2405 | kern_path_mountpoint(int dfd, const char *name, struct path *path, | ||
2406 | unsigned int flags) | ||
2407 | { | ||
2408 | struct filename s = {.name = name}; | ||
2409 | return filename_mountpoint(dfd, &s, path, flags); | ||
2410 | } | ||
2411 | EXPORT_SYMBOL(kern_path_mountpoint); | ||
2412 | |||
2400 | /* | 2413 | /* |
2401 | * It's inline, so penalty for filesystems that don't use sticky bit is | 2414 | * It's inline, so penalty for filesystems that don't use sticky bit is |
2402 | * minimal. | 2415 | * minimal. |