diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-22 04:41:10 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-14 08:33:43 -0400 |
commit | 2675a4eb6a9f1240098721c8a84ede28abd9d7b3 (patch) | |
tree | 76714224336154a2ca645b67d7f6d0f004bc569a /fs | |
parent | 30d904947459cca2beb69e0110716f5248b31f2a (diff) |
fs/namei.c: get do_last() and friends return int
Same conventions as for ->atomic_open(). Trimmed the
forest of labels a bit, while we are at it...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/namei.c | 150 |
1 files changed, 70 insertions, 80 deletions
diff --git a/fs/namei.c b/fs/namei.c index aaff8a862151..16256d915cb8 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2193,18 +2193,17 @@ static int may_o_create(struct path *dir, struct dentry *dentry, umode_t mode) | |||
2193 | return security_inode_create(dir->dentry->d_inode, dentry, mode); | 2193 | return security_inode_create(dir->dentry->d_inode, dentry, mode); |
2194 | } | 2194 | } |
2195 | 2195 | ||
2196 | static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | 2196 | static int atomic_open(struct nameidata *nd, struct dentry *dentry, |
2197 | struct path *path, struct file *file, | 2197 | struct path *path, struct file *file, |
2198 | const struct open_flags *op, | 2198 | const struct open_flags *op, |
2199 | bool *want_write, bool need_lookup, | 2199 | bool *want_write, bool need_lookup, |
2200 | int *opened) | 2200 | int *opened) |
2201 | { | 2201 | { |
2202 | struct inode *dir = nd->path.dentry->d_inode; | 2202 | struct inode *dir = nd->path.dentry->d_inode; |
2203 | unsigned open_flag = open_to_namei_flags(op->open_flag); | 2203 | unsigned open_flag = open_to_namei_flags(op->open_flag); |
2204 | umode_t mode; | 2204 | umode_t mode; |
2205 | int error; | 2205 | int error; |
2206 | int acc_mode; | 2206 | int acc_mode; |
2207 | struct file *filp = NULL; | ||
2208 | int create_error = 0; | 2207 | int create_error = 0; |
2209 | struct dentry *const DENTRY_NOT_SET = (void *) -1UL; | 2208 | struct dentry *const DENTRY_NOT_SET = (void *) -1UL; |
2210 | 2209 | ||
@@ -2212,7 +2211,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2212 | 2211 | ||
2213 | /* Don't create child dentry for a dead directory. */ | 2212 | /* Don't create child dentry for a dead directory. */ |
2214 | if (unlikely(IS_DEADDIR(dir))) { | 2213 | if (unlikely(IS_DEADDIR(dir))) { |
2215 | filp = ERR_PTR(-ENOENT); | 2214 | error = -ENOENT; |
2216 | goto out; | 2215 | goto out; |
2217 | } | 2216 | } |
2218 | 2217 | ||
@@ -2276,7 +2275,6 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2276 | if (error < 0) { | 2275 | if (error < 0) { |
2277 | if (create_error && error == -ENOENT) | 2276 | if (create_error && error == -ENOENT) |
2278 | error = create_error; | 2277 | error = create_error; |
2279 | filp = ERR_PTR(error); | ||
2280 | goto out; | 2278 | goto out; |
2281 | } | 2279 | } |
2282 | 2280 | ||
@@ -2288,7 +2286,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2288 | 2286 | ||
2289 | if (error) { /* returned 1, that is */ | 2287 | if (error) { /* returned 1, that is */ |
2290 | if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { | 2288 | if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { |
2291 | filp = ERR_PTR(-EIO); | 2289 | error = -EIO; |
2292 | goto out; | 2290 | goto out; |
2293 | } | 2291 | } |
2294 | if (file->f_path.dentry) { | 2292 | if (file->f_path.dentry) { |
@@ -2302,27 +2300,24 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2302 | * We didn't have the inode before the open, so check open permission | 2300 | * We didn't have the inode before the open, so check open permission |
2303 | * here. | 2301 | * here. |
2304 | */ | 2302 | */ |
2305 | filp = file; | 2303 | error = may_open(&file->f_path, acc_mode, open_flag); |
2306 | error = may_open(&filp->f_path, acc_mode, open_flag); | 2304 | if (error) |
2307 | if (error) { | 2305 | fput(file); |
2308 | fput(filp); | ||
2309 | filp = ERR_PTR(error); | ||
2310 | } | ||
2311 | 2306 | ||
2312 | out: | 2307 | out: |
2313 | dput(dentry); | 2308 | dput(dentry); |
2314 | return filp; | 2309 | return error; |
2315 | 2310 | ||
2316 | no_open: | 2311 | no_open: |
2317 | if (need_lookup) { | 2312 | if (need_lookup) { |
2318 | dentry = lookup_real(dir, dentry, nd); | 2313 | dentry = lookup_real(dir, dentry, nd); |
2319 | if (IS_ERR(dentry)) | 2314 | if (IS_ERR(dentry)) |
2320 | return ERR_CAST(dentry); | 2315 | return PTR_ERR(dentry); |
2321 | 2316 | ||
2322 | if (create_error) { | 2317 | if (create_error) { |
2323 | int open_flag = op->open_flag; | 2318 | int open_flag = op->open_flag; |
2324 | 2319 | ||
2325 | filp = ERR_PTR(create_error); | 2320 | error = create_error; |
2326 | if ((open_flag & O_EXCL)) { | 2321 | if ((open_flag & O_EXCL)) { |
2327 | if (!dentry->d_inode) | 2322 | if (!dentry->d_inode) |
2328 | goto out; | 2323 | goto out; |
@@ -2338,7 +2333,7 @@ no_open: | |||
2338 | looked_up: | 2333 | looked_up: |
2339 | path->dentry = dentry; | 2334 | path->dentry = dentry; |
2340 | path->mnt = nd->path.mnt; | 2335 | path->mnt = nd->path.mnt; |
2341 | return NULL; | 2336 | return 1; |
2342 | } | 2337 | } |
2343 | 2338 | ||
2344 | /* | 2339 | /* |
@@ -2349,10 +2344,10 @@ looked_up: | |||
2349 | * Returns open file or NULL on success, error otherwise. NULL means no open | 2344 | * Returns open file or NULL on success, error otherwise. NULL means no open |
2350 | * was performed, only lookup. | 2345 | * was performed, only lookup. |
2351 | */ | 2346 | */ |
2352 | static struct file *lookup_open(struct nameidata *nd, struct path *path, | 2347 | static int lookup_open(struct nameidata *nd, struct path *path, |
2353 | struct file *file, | 2348 | struct file *file, |
2354 | const struct open_flags *op, | 2349 | const struct open_flags *op, |
2355 | bool *want_write, int *opened) | 2350 | bool *want_write, int *opened) |
2356 | { | 2351 | { |
2357 | struct dentry *dir = nd->path.dentry; | 2352 | struct dentry *dir = nd->path.dentry; |
2358 | struct inode *dir_inode = dir->d_inode; | 2353 | struct inode *dir_inode = dir->d_inode; |
@@ -2363,7 +2358,7 @@ static struct file *lookup_open(struct nameidata *nd, struct path *path, | |||
2363 | *opened &= ~FILE_CREATED; | 2358 | *opened &= ~FILE_CREATED; |
2364 | dentry = lookup_dcache(&nd->last, dir, nd, &need_lookup); | 2359 | dentry = lookup_dcache(&nd->last, dir, nd, &need_lookup); |
2365 | if (IS_ERR(dentry)) | 2360 | if (IS_ERR(dentry)) |
2366 | return ERR_CAST(dentry); | 2361 | return PTR_ERR(dentry); |
2367 | 2362 | ||
2368 | /* Cached positive dentry: will open in f_op->open */ | 2363 | /* Cached positive dentry: will open in f_op->open */ |
2369 | if (!need_lookup && dentry->d_inode) | 2364 | if (!need_lookup && dentry->d_inode) |
@@ -2379,7 +2374,7 @@ static struct file *lookup_open(struct nameidata *nd, struct path *path, | |||
2379 | 2374 | ||
2380 | dentry = lookup_real(dir_inode, dentry, nd); | 2375 | dentry = lookup_real(dir_inode, dentry, nd); |
2381 | if (IS_ERR(dentry)) | 2376 | if (IS_ERR(dentry)) |
2382 | return ERR_CAST(dentry); | 2377 | return PTR_ERR(dentry); |
2383 | } | 2378 | } |
2384 | 2379 | ||
2385 | /* Negative dentry, just create the file */ | 2380 | /* Negative dentry, just create the file */ |
@@ -2409,26 +2404,25 @@ static struct file *lookup_open(struct nameidata *nd, struct path *path, | |||
2409 | out_no_open: | 2404 | out_no_open: |
2410 | path->dentry = dentry; | 2405 | path->dentry = dentry; |
2411 | path->mnt = nd->path.mnt; | 2406 | path->mnt = nd->path.mnt; |
2412 | return NULL; | 2407 | return 1; |
2413 | 2408 | ||
2414 | out_dput: | 2409 | out_dput: |
2415 | dput(dentry); | 2410 | dput(dentry); |
2416 | return ERR_PTR(error); | 2411 | return error; |
2417 | } | 2412 | } |
2418 | 2413 | ||
2419 | /* | 2414 | /* |
2420 | * Handle the last step of open() | 2415 | * Handle the last step of open() |
2421 | */ | 2416 | */ |
2422 | static struct file *do_last(struct nameidata *nd, struct path *path, | 2417 | static int do_last(struct nameidata *nd, struct path *path, |
2423 | struct file *file, const struct open_flags *op, | 2418 | struct file *file, const struct open_flags *op, |
2424 | int *opened, const char *pathname) | 2419 | int *opened, const char *pathname) |
2425 | { | 2420 | { |
2426 | struct dentry *dir = nd->path.dentry; | 2421 | struct dentry *dir = nd->path.dentry; |
2427 | int open_flag = op->open_flag; | 2422 | int open_flag = op->open_flag; |
2428 | bool will_truncate = (open_flag & O_TRUNC) != 0; | 2423 | bool will_truncate = (open_flag & O_TRUNC) != 0; |
2429 | bool want_write = false; | 2424 | bool want_write = false; |
2430 | int acc_mode = op->acc_mode; | 2425 | int acc_mode = op->acc_mode; |
2431 | struct file *filp; | ||
2432 | struct inode *inode; | 2426 | struct inode *inode; |
2433 | bool symlink_ok = false; | 2427 | bool symlink_ok = false; |
2434 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; | 2428 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; |
@@ -2443,22 +2437,22 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2443 | case LAST_DOT: | 2437 | case LAST_DOT: |
2444 | error = handle_dots(nd, nd->last_type); | 2438 | error = handle_dots(nd, nd->last_type); |
2445 | if (error) | 2439 | if (error) |
2446 | return ERR_PTR(error); | 2440 | return error; |
2447 | /* fallthrough */ | 2441 | /* fallthrough */ |
2448 | case LAST_ROOT: | 2442 | case LAST_ROOT: |
2449 | error = complete_walk(nd); | 2443 | error = complete_walk(nd); |
2450 | if (error) | 2444 | if (error) |
2451 | return ERR_PTR(error); | 2445 | return error; |
2452 | audit_inode(pathname, nd->path.dentry); | 2446 | audit_inode(pathname, nd->path.dentry); |
2453 | if (open_flag & O_CREAT) { | 2447 | if (open_flag & O_CREAT) { |
2454 | error = -EISDIR; | 2448 | error = -EISDIR; |
2455 | goto exit; | 2449 | goto out; |
2456 | } | 2450 | } |
2457 | goto finish_open; | 2451 | goto finish_open; |
2458 | case LAST_BIND: | 2452 | case LAST_BIND: |
2459 | error = complete_walk(nd); | 2453 | error = complete_walk(nd); |
2460 | if (error) | 2454 | if (error) |
2461 | return ERR_PTR(error); | 2455 | return error; |
2462 | audit_inode(pathname, dir); | 2456 | audit_inode(pathname, dir); |
2463 | goto finish_open; | 2457 | goto finish_open; |
2464 | } | 2458 | } |
@@ -2474,7 +2468,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2474 | goto finish_lookup; | 2468 | goto finish_lookup; |
2475 | 2469 | ||
2476 | if (error < 0) | 2470 | if (error < 0) |
2477 | goto exit; | 2471 | goto out; |
2478 | 2472 | ||
2479 | BUG_ON(nd->inode != dir->d_inode); | 2473 | BUG_ON(nd->inode != dir->d_inode); |
2480 | } else { | 2474 | } else { |
@@ -2486,29 +2480,29 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2486 | */ | 2480 | */ |
2487 | error = complete_walk(nd); | 2481 | error = complete_walk(nd); |
2488 | if (error) | 2482 | if (error) |
2489 | return ERR_PTR(error); | 2483 | return error; |
2490 | 2484 | ||
2491 | audit_inode(pathname, dir); | 2485 | audit_inode(pathname, dir); |
2492 | error = -EISDIR; | 2486 | error = -EISDIR; |
2493 | /* trailing slashes? */ | 2487 | /* trailing slashes? */ |
2494 | if (nd->last.name[nd->last.len]) | 2488 | if (nd->last.name[nd->last.len]) |
2495 | goto exit; | 2489 | goto out; |
2496 | } | 2490 | } |
2497 | 2491 | ||
2498 | retry_lookup: | 2492 | retry_lookup: |
2499 | mutex_lock(&dir->d_inode->i_mutex); | 2493 | mutex_lock(&dir->d_inode->i_mutex); |
2500 | filp = lookup_open(nd, path, file, op, &want_write, opened); | 2494 | error = lookup_open(nd, path, file, op, &want_write, opened); |
2501 | mutex_unlock(&dir->d_inode->i_mutex); | 2495 | mutex_unlock(&dir->d_inode->i_mutex); |
2502 | 2496 | ||
2503 | if (filp) { | 2497 | if (error <= 0) { |
2504 | if (IS_ERR(filp)) | 2498 | if (error) |
2505 | goto out; | 2499 | goto out; |
2506 | 2500 | ||
2507 | if ((*opened & FILE_CREATED) || | 2501 | if ((*opened & FILE_CREATED) || |
2508 | !S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | 2502 | !S_ISREG(file->f_path.dentry->d_inode->i_mode)) |
2509 | will_truncate = false; | 2503 | will_truncate = false; |
2510 | 2504 | ||
2511 | audit_inode(pathname, filp->f_path.dentry); | 2505 | audit_inode(pathname, file->f_path.dentry); |
2512 | goto opened; | 2506 | goto opened; |
2513 | } | 2507 | } |
2514 | 2508 | ||
@@ -2554,18 +2548,18 @@ finish_lookup: | |||
2554 | error = -ENOENT; | 2548 | error = -ENOENT; |
2555 | if (!inode) { | 2549 | if (!inode) { |
2556 | path_to_nameidata(path, nd); | 2550 | path_to_nameidata(path, nd); |
2557 | goto exit; | 2551 | goto out; |
2558 | } | 2552 | } |
2559 | 2553 | ||
2560 | if (should_follow_link(inode, !symlink_ok)) { | 2554 | if (should_follow_link(inode, !symlink_ok)) { |
2561 | if (nd->flags & LOOKUP_RCU) { | 2555 | if (nd->flags & LOOKUP_RCU) { |
2562 | if (unlikely(unlazy_walk(nd, path->dentry))) { | 2556 | if (unlikely(unlazy_walk(nd, path->dentry))) { |
2563 | error = -ECHILD; | 2557 | error = -ECHILD; |
2564 | goto exit; | 2558 | goto out; |
2565 | } | 2559 | } |
2566 | } | 2560 | } |
2567 | BUG_ON(inode != path->dentry->d_inode); | 2561 | BUG_ON(inode != path->dentry->d_inode); |
2568 | return NULL; | 2562 | return 1; |
2569 | } | 2563 | } |
2570 | 2564 | ||
2571 | if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) { | 2565 | if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path->mnt) { |
@@ -2581,14 +2575,14 @@ finish_lookup: | |||
2581 | error = complete_walk(nd); | 2575 | error = complete_walk(nd); |
2582 | if (error) { | 2576 | if (error) { |
2583 | path_put(&save_parent); | 2577 | path_put(&save_parent); |
2584 | return ERR_PTR(error); | 2578 | return error; |
2585 | } | 2579 | } |
2586 | error = -EISDIR; | 2580 | error = -EISDIR; |
2587 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) | 2581 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) |
2588 | goto exit; | 2582 | goto out; |
2589 | error = -ENOTDIR; | 2583 | error = -ENOTDIR; |
2590 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) | 2584 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) |
2591 | goto exit; | 2585 | goto out; |
2592 | audit_inode(pathname, nd->path.dentry); | 2586 | audit_inode(pathname, nd->path.dentry); |
2593 | finish_open: | 2587 | finish_open: |
2594 | if (!S_ISREG(nd->inode->i_mode)) | 2588 | if (!S_ISREG(nd->inode->i_mode)) |
@@ -2597,32 +2591,30 @@ finish_open: | |||
2597 | if (will_truncate) { | 2591 | if (will_truncate) { |
2598 | error = mnt_want_write(nd->path.mnt); | 2592 | error = mnt_want_write(nd->path.mnt); |
2599 | if (error) | 2593 | if (error) |
2600 | goto exit; | 2594 | goto out; |
2601 | want_write = true; | 2595 | want_write = true; |
2602 | } | 2596 | } |
2603 | finish_open_created: | 2597 | finish_open_created: |
2604 | error = may_open(&nd->path, acc_mode, open_flag); | 2598 | error = may_open(&nd->path, acc_mode, open_flag); |
2605 | if (error) | 2599 | if (error) |
2606 | goto exit; | 2600 | goto out; |
2607 | file->f_path.mnt = nd->path.mnt; | 2601 | file->f_path.mnt = nd->path.mnt; |
2608 | error = finish_open(file, nd->path.dentry, NULL, opened); | 2602 | error = finish_open(file, nd->path.dentry, NULL, opened); |
2609 | if (error) { | 2603 | if (error) { |
2610 | filp = ERR_PTR(error); | ||
2611 | if (error == -EOPENSTALE) | 2604 | if (error == -EOPENSTALE) |
2612 | goto stale_open; | 2605 | goto stale_open; |
2613 | goto out; | 2606 | goto out; |
2614 | } | 2607 | } |
2615 | filp = file; | ||
2616 | opened: | 2608 | opened: |
2617 | error = open_check_o_direct(filp); | 2609 | error = open_check_o_direct(file); |
2618 | if (error) | 2610 | if (error) |
2619 | goto exit_fput; | 2611 | goto exit_fput; |
2620 | error = ima_file_check(filp, op->acc_mode); | 2612 | error = ima_file_check(file, op->acc_mode); |
2621 | if (error) | 2613 | if (error) |
2622 | goto exit_fput; | 2614 | goto exit_fput; |
2623 | 2615 | ||
2624 | if (will_truncate) { | 2616 | if (will_truncate) { |
2625 | error = handle_truncate(filp); | 2617 | error = handle_truncate(file); |
2626 | if (error) | 2618 | if (error) |
2627 | goto exit_fput; | 2619 | goto exit_fput; |
2628 | } | 2620 | } |
@@ -2631,16 +2623,14 @@ out: | |||
2631 | mnt_drop_write(nd->path.mnt); | 2623 | mnt_drop_write(nd->path.mnt); |
2632 | path_put(&save_parent); | 2624 | path_put(&save_parent); |
2633 | terminate_walk(nd); | 2625 | terminate_walk(nd); |
2634 | return filp; | 2626 | return error; |
2635 | 2627 | ||
2636 | exit_dput: | 2628 | exit_dput: |
2637 | path_put_conditional(path, nd); | 2629 | path_put_conditional(path, nd); |
2638 | exit: | ||
2639 | filp = ERR_PTR(error); | ||
2640 | goto out; | 2630 | goto out; |
2641 | exit_fput: | 2631 | exit_fput: |
2642 | fput(filp); | 2632 | fput(file); |
2643 | goto exit; | 2633 | goto out; |
2644 | 2634 | ||
2645 | stale_open: | 2635 | stale_open: |
2646 | /* If no saved parent or already retried then can't retry */ | 2636 | /* If no saved parent or already retried then can't retry */ |
@@ -2666,7 +2656,6 @@ static struct file *path_openat(int dfd, const char *pathname, | |||
2666 | { | 2656 | { |
2667 | struct file *base = NULL; | 2657 | struct file *base = NULL; |
2668 | struct file *file; | 2658 | struct file *file; |
2669 | struct file *res; | ||
2670 | struct path path; | 2659 | struct path path; |
2671 | int opened = 0; | 2660 | int opened = 0; |
2672 | int error; | 2661 | int error; |
@@ -2679,29 +2668,29 @@ static struct file *path_openat(int dfd, const char *pathname, | |||
2679 | 2668 | ||
2680 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); | 2669 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); |
2681 | if (unlikely(error)) | 2670 | if (unlikely(error)) |
2682 | goto out_filp; | 2671 | goto out; |
2683 | 2672 | ||
2684 | current->total_link_count = 0; | 2673 | current->total_link_count = 0; |
2685 | error = link_path_walk(pathname, nd); | 2674 | error = link_path_walk(pathname, nd); |
2686 | if (unlikely(error)) | 2675 | if (unlikely(error)) |
2687 | goto out_filp; | 2676 | goto out; |
2688 | 2677 | ||
2689 | res = do_last(nd, &path, file, op, &opened, pathname); | 2678 | error = do_last(nd, &path, file, op, &opened, pathname); |
2690 | while (unlikely(!res)) { /* trailing symlink */ | 2679 | while (unlikely(error > 0)) { /* trailing symlink */ |
2691 | struct path link = path; | 2680 | struct path link = path; |
2692 | void *cookie; | 2681 | void *cookie; |
2693 | if (!(nd->flags & LOOKUP_FOLLOW)) { | 2682 | if (!(nd->flags & LOOKUP_FOLLOW)) { |
2694 | path_put_conditional(&path, nd); | 2683 | path_put_conditional(&path, nd); |
2695 | path_put(&nd->path); | 2684 | path_put(&nd->path); |
2696 | res = ERR_PTR(-ELOOP); | 2685 | error = -ELOOP; |
2697 | break; | 2686 | break; |
2698 | } | 2687 | } |
2699 | nd->flags |= LOOKUP_PARENT; | 2688 | nd->flags |= LOOKUP_PARENT; |
2700 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); | 2689 | nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); |
2701 | error = follow_link(&link, nd, &cookie); | 2690 | error = follow_link(&link, nd, &cookie); |
2702 | if (unlikely(error)) | 2691 | if (unlikely(error)) |
2703 | goto out_filp; | 2692 | break; |
2704 | res = do_last(nd, &path, file, op, &opened, pathname); | 2693 | error = do_last(nd, &path, file, op, &opened, pathname); |
2705 | put_link(nd, &link, cookie); | 2694 | put_link(nd, &link, cookie); |
2706 | } | 2695 | } |
2707 | out: | 2696 | out: |
@@ -2709,19 +2698,20 @@ out: | |||
2709 | path_put(&nd->root); | 2698 | path_put(&nd->root); |
2710 | if (base) | 2699 | if (base) |
2711 | fput(base); | 2700 | fput(base); |
2712 | if (!(opened & FILE_OPENED)) | 2701 | if (!(opened & FILE_OPENED)) { |
2702 | BUG_ON(!error); | ||
2713 | put_filp(file); | 2703 | put_filp(file); |
2714 | if (res == ERR_PTR(-EOPENSTALE)) { | ||
2715 | if (flags & LOOKUP_RCU) | ||
2716 | res = ERR_PTR(-ECHILD); | ||
2717 | else | ||
2718 | res = ERR_PTR(-ESTALE); | ||
2719 | } | 2704 | } |
2720 | return res; | 2705 | if (unlikely(error)) { |
2721 | 2706 | if (error == -EOPENSTALE) { | |
2722 | out_filp: | 2707 | if (flags & LOOKUP_RCU) |
2723 | res = ERR_PTR(error); | 2708 | error = -ECHILD; |
2724 | goto out; | 2709 | else |
2710 | error = -ESTALE; | ||
2711 | } | ||
2712 | file = ERR_PTR(error); | ||
2713 | } | ||
2714 | return file; | ||
2725 | } | 2715 | } |
2726 | 2716 | ||
2727 | struct file *do_filp_open(int dfd, const char *pathname, | 2717 | struct file *do_filp_open(int dfd, const char *pathname, |