@@ -2054,75 +2054,55 @@ struct dentry *d_make_root(struct inode *root_inode)
2054
2054
}
2055
2055
EXPORT_SYMBOL (d_make_root );
2056
2056
2057
- static struct dentry * __d_instantiate_anon (struct dentry * dentry ,
2058
- struct inode * inode ,
2059
- bool disconnected )
2060
- {
2061
- struct dentry * res ;
2062
- unsigned add_flags ;
2063
-
2064
- security_d_instantiate (dentry , inode );
2065
- spin_lock (& inode -> i_lock );
2066
- res = __d_find_any_alias (inode );
2067
- if (res ) {
2068
- spin_unlock (& inode -> i_lock );
2069
- dput (dentry );
2070
- goto out_iput ;
2071
- }
2072
-
2073
- /* attach a disconnected dentry */
2074
- add_flags = d_flags_for_inode (inode );
2075
-
2076
- if (disconnected )
2077
- add_flags |= DCACHE_DISCONNECTED ;
2078
-
2079
- spin_lock (& dentry -> d_lock );
2080
- __d_set_inode_and_type (dentry , inode , add_flags );
2081
- hlist_add_head (& dentry -> d_u .d_alias , & inode -> i_dentry );
2082
- if (!disconnected ) {
2083
- hlist_bl_lock (& dentry -> d_sb -> s_roots );
2084
- hlist_bl_add_head (& dentry -> d_hash , & dentry -> d_sb -> s_roots );
2085
- hlist_bl_unlock (& dentry -> d_sb -> s_roots );
2086
- }
2087
- spin_unlock (& dentry -> d_lock );
2088
- spin_unlock (& inode -> i_lock );
2089
-
2090
- return dentry ;
2091
-
2092
- out_iput :
2093
- iput (inode );
2094
- return res ;
2095
- }
2096
-
2097
- struct dentry * d_instantiate_anon (struct dentry * dentry , struct inode * inode )
2098
- {
2099
- return __d_instantiate_anon (dentry , inode , true);
2100
- }
2101
- EXPORT_SYMBOL (d_instantiate_anon );
2102
-
2103
2057
static struct dentry * __d_obtain_alias (struct inode * inode , bool disconnected )
2104
2058
{
2105
- struct dentry * tmp ;
2106
- struct dentry * res ;
2059
+ struct super_block * sb ;
2060
+ struct dentry * new , * res ;
2107
2061
2108
2062
if (!inode )
2109
2063
return ERR_PTR (- ESTALE );
2110
2064
if (IS_ERR (inode ))
2111
2065
return ERR_CAST (inode );
2112
2066
2113
- res = d_find_any_alias (inode );
2067
+ sb = inode -> i_sb ;
2068
+
2069
+ res = d_find_any_alias (inode ); /* existing alias? */
2114
2070
if (res )
2115
- goto out_iput ;
2071
+ goto out ;
2116
2072
2117
- tmp = d_alloc_anon (inode -> i_sb );
2118
- if (!tmp ) {
2073
+ new = d_alloc_anon (sb );
2074
+ if (!new ) {
2119
2075
res = ERR_PTR (- ENOMEM );
2120
- goto out_iput ;
2076
+ goto out ;
2121
2077
}
2122
2078
2123
- return __d_instantiate_anon (tmp , inode , disconnected );
2079
+ security_d_instantiate (new , inode );
2080
+ spin_lock (& inode -> i_lock );
2081
+ res = __d_find_any_alias (inode ); /* recheck under lock */
2082
+ if (likely (!res )) { /* still no alias, attach a disconnected dentry */
2083
+ unsigned add_flags = d_flags_for_inode (inode );
2084
+
2085
+ if (disconnected )
2086
+ add_flags |= DCACHE_DISCONNECTED ;
2087
+
2088
+ spin_lock (& new -> d_lock );
2089
+ __d_set_inode_and_type (new , inode , add_flags );
2090
+ hlist_add_head (& new -> d_u .d_alias , & inode -> i_dentry );
2091
+ if (!disconnected ) {
2092
+ hlist_bl_lock (& sb -> s_roots );
2093
+ hlist_bl_add_head (& new -> d_hash , & sb -> s_roots );
2094
+ hlist_bl_unlock (& sb -> s_roots );
2095
+ }
2096
+ spin_unlock (& new -> d_lock );
2097
+ spin_unlock (& inode -> i_lock );
2098
+ inode = NULL ; /* consumed by new->d_inode */
2099
+ res = new ;
2100
+ } else {
2101
+ spin_unlock (& inode -> i_lock );
2102
+ dput (new );
2103
+ }
2124
2104
2125
- out_iput :
2105
+ out :
2126
2106
iput (inode );
2127
2107
return res ;
2128
2108
}
0 commit comments