diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-10-12 18:46:26 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-19 13:00:10 -0500 |
commit | 427c77d4619657c483c49b28ca1813bb33e857b0 (patch) | |
tree | 626cb6d8afe9d5b1408e470187e921aebd72fa1b /fs/dcache.c | |
parent | ca5358ef75fc69fee5322a38a340f5739d997c10 (diff) |
d_add_ci() should just accept a hashed exact match if it finds one
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 46 |
1 files changed, 7 insertions, 39 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index e90aa825cc03..e605e90d0f0a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1888,51 +1888,19 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, | |||
1888 | * if not go ahead and create it now. | 1888 | * if not go ahead and create it now. |
1889 | */ | 1889 | */ |
1890 | found = d_hash_and_lookup(dentry->d_parent, name); | 1890 | found = d_hash_and_lookup(dentry->d_parent, name); |
1891 | if (unlikely(IS_ERR(found))) | ||
1892 | goto err_out; | ||
1893 | if (!found) { | 1891 | if (!found) { |
1894 | new = d_alloc(dentry->d_parent, name); | 1892 | new = d_alloc(dentry->d_parent, name); |
1895 | if (!new) { | 1893 | if (!new) { |
1896 | found = ERR_PTR(-ENOMEM); | 1894 | found = ERR_PTR(-ENOMEM); |
1897 | goto err_out; | 1895 | } else { |
1898 | } | 1896 | found = d_splice_alias(inode, new); |
1899 | 1897 | if (found) { | |
1900 | found = d_splice_alias(inode, new); | 1898 | dput(new); |
1901 | if (found) { | 1899 | return found; |
1902 | dput(new); | 1900 | } |
1903 | return found; | 1901 | return new; |
1904 | } | ||
1905 | return new; | ||
1906 | } | ||
1907 | |||
1908 | /* | ||
1909 | * If a matching dentry exists, and it's not negative use it. | ||
1910 | * | ||
1911 | * Decrement the reference count to balance the iget() done | ||
1912 | * earlier on. | ||
1913 | */ | ||
1914 | if (found->d_inode) { | ||
1915 | if (unlikely(found->d_inode != inode)) { | ||
1916 | /* This can't happen because bad inodes are unhashed. */ | ||
1917 | BUG_ON(!is_bad_inode(inode)); | ||
1918 | BUG_ON(!is_bad_inode(found->d_inode)); | ||
1919 | } | 1902 | } |
1920 | iput(inode); | ||
1921 | return found; | ||
1922 | } | 1903 | } |
1923 | |||
1924 | /* | ||
1925 | * Negative dentry: instantiate it unless the inode is a directory and | ||
1926 | * already has a dentry. | ||
1927 | */ | ||
1928 | new = d_splice_alias(inode, found); | ||
1929 | if (new) { | ||
1930 | dput(found); | ||
1931 | found = new; | ||
1932 | } | ||
1933 | return found; | ||
1934 | |||
1935 | err_out: | ||
1936 | iput(inode); | 1904 | iput(inode); |
1937 | return found; | 1905 | return found; |
1938 | } | 1906 | } |