aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-06-22 04:41:10 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-14 08:33:43 -0400
commit2675a4eb6a9f1240098721c8a84ede28abd9d7b3 (patch)
tree76714224336154a2ca645b67d7f6d0f004bc569a /fs
parent30d904947459cca2beb69e0110716f5248b31f2a (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.c150
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
2196static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, 2196static 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
2312out: 2307out:
2313 dput(dentry); 2308 dput(dentry);
2314 return filp; 2309 return error;
2315 2310
2316no_open: 2311no_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:
2338looked_up: 2333looked_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 */
2352static struct file *lookup_open(struct nameidata *nd, struct path *path, 2347static 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,
2409out_no_open: 2404out_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
2414out_dput: 2409out_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 */
2422static struct file *do_last(struct nameidata *nd, struct path *path, 2417static 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
2498retry_lookup: 2492retry_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);
2593finish_open: 2587finish_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 }
2603finish_open_created: 2597finish_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;
2616opened: 2608opened:
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
2636exit_dput: 2628exit_dput:
2637 path_put_conditional(path, nd); 2629 path_put_conditional(path, nd);
2638exit:
2639 filp = ERR_PTR(error);
2640 goto out; 2630 goto out;
2641exit_fput: 2631exit_fput:
2642 fput(filp); 2632 fput(file);
2643 goto exit; 2633 goto out;
2644 2634
2645stale_open: 2635stale_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 }
2707out: 2696out:
@@ -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) {
2722out_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
2727struct file *do_filp_open(int dfd, const char *pathname, 2717struct file *do_filp_open(int dfd, const char *pathname,