| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
|---|
| 3 | 4 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This copyrighted material is made available to anyone wishing to use, |
|---|
| 6 | | - * modify, copy, or redistribute it subject to the terms and conditions |
|---|
| 7 | | - * of the GNU General Public License version 2. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #include <linux/spinlock.h> |
|---|
| .. | .. |
|---|
| 41 | 38 | struct inode *inode; |
|---|
| 42 | 39 | struct gfs2_holder d_gh; |
|---|
| 43 | 40 | struct gfs2_inode *ip = NULL; |
|---|
| 44 | | - int error; |
|---|
| 41 | + int error, valid = 0; |
|---|
| 45 | 42 | int had_lock = 0; |
|---|
| 46 | 43 | |
|---|
| 47 | 44 | if (flags & LOOKUP_RCU) |
|---|
| .. | .. |
|---|
| 54 | 51 | |
|---|
| 55 | 52 | if (inode) { |
|---|
| 56 | 53 | if (is_bad_inode(inode)) |
|---|
| 57 | | - goto invalid; |
|---|
| 54 | + goto out; |
|---|
| 58 | 55 | ip = GFS2_I(inode); |
|---|
| 59 | 56 | } |
|---|
| 60 | 57 | |
|---|
| 61 | | - if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) |
|---|
| 62 | | - goto valid; |
|---|
| 58 | + if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) { |
|---|
| 59 | + valid = 1; |
|---|
| 60 | + goto out; |
|---|
| 61 | + } |
|---|
| 63 | 62 | |
|---|
| 64 | 63 | had_lock = (gfs2_glock_is_locked_by_me(dip->i_gl) != NULL); |
|---|
| 65 | 64 | if (!had_lock) { |
|---|
| 66 | 65 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); |
|---|
| 67 | 66 | if (error) |
|---|
| 68 | | - goto fail; |
|---|
| 69 | | - } |
|---|
| 70 | | - |
|---|
| 71 | | - error = gfs2_dir_check(d_inode(parent), &dentry->d_name, ip); |
|---|
| 72 | | - switch (error) { |
|---|
| 73 | | - case 0: |
|---|
| 74 | | - if (!inode) |
|---|
| 75 | | - goto invalid_gunlock; |
|---|
| 76 | | - break; |
|---|
| 77 | | - case -ENOENT: |
|---|
| 78 | | - if (!inode) |
|---|
| 79 | | - goto valid_gunlock; |
|---|
| 80 | | - goto invalid_gunlock; |
|---|
| 81 | | - default: |
|---|
| 82 | | - goto fail_gunlock; |
|---|
| 67 | + goto out; |
|---|
| 83 | 68 | } |
|---|
| 84 | 69 | |
|---|
| 85 | | -valid_gunlock: |
|---|
| 70 | + error = gfs2_dir_check(d_inode(parent), &dentry->d_name, ip); |
|---|
| 71 | + valid = inode ? !error : (error == -ENOENT); |
|---|
| 72 | + |
|---|
| 86 | 73 | if (!had_lock) |
|---|
| 87 | 74 | gfs2_glock_dq_uninit(&d_gh); |
|---|
| 88 | | -valid: |
|---|
| 75 | +out: |
|---|
| 89 | 76 | dput(parent); |
|---|
| 90 | | - return 1; |
|---|
| 91 | | - |
|---|
| 92 | | -invalid_gunlock: |
|---|
| 93 | | - if (!had_lock) |
|---|
| 94 | | - gfs2_glock_dq_uninit(&d_gh); |
|---|
| 95 | | -invalid: |
|---|
| 96 | | - dput(parent); |
|---|
| 97 | | - return 0; |
|---|
| 98 | | - |
|---|
| 99 | | -fail_gunlock: |
|---|
| 100 | | - gfs2_glock_dq_uninit(&d_gh); |
|---|
| 101 | | -fail: |
|---|
| 102 | | - dput(parent); |
|---|
| 103 | | - return 0; |
|---|
| 77 | + return valid; |
|---|
| 104 | 78 | } |
|---|
| 105 | 79 | |
|---|
| 106 | 80 | static int gfs2_dhash(const struct dentry *dentry, struct qstr *str) |
|---|