summaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-03-08 12:44:17 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2016-03-14 00:17:20 -0400
commit668d0cd56ef7bc71be6dd8c081007221e09d9a86 (patch)
treee4e61bdd16fde1ad932861a23978601c2530f32a /fs/dcache.c
parente12a4e8a04a9ef84ba645379c56abad1a0ca9dbd (diff)
replace d_add_unique() with saner primitive
new primitive: d_exact_alias(dentry, inode). If there is an unhashed dentry with the same name/parent and given inode, rehash, grab and return it. Otherwise, return NULL. The only caller of d_add_unique() switched to d_exact_alias() + d_splice_alias(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c125
1 files changed, 50 insertions, 75 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 2398f9f94337..4d20bf5c609b 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1782,81 +1782,6 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
1782EXPORT_SYMBOL(d_instantiate); 1782EXPORT_SYMBOL(d_instantiate);
1783 1783
1784/** 1784/**
1785 * d_instantiate_unique - instantiate a non-aliased dentry
1786 * @entry: dentry to instantiate
1787 * @inode: inode to attach to this dentry
1788 *
1789 * Fill in inode information in the entry. On success, it returns NULL.
1790 * If an unhashed alias of "entry" already exists, then we return the
1791 * aliased dentry instead and drop one reference to inode.
1792 *
1793 * Note that in order to avoid conflicts with rename() etc, the caller
1794 * had better be holding the parent directory semaphore.
1795 *
1796 * This also assumes that the inode count has been incremented
1797 * (or otherwise set) by the caller to indicate that it is now
1798 * in use by the dcache.
1799 */
1800static struct dentry *__d_instantiate_unique(struct dentry *entry,
1801 struct inode *inode)
1802{
1803 struct dentry *alias;
1804 int len = entry->d_name.len;
1805 const char *name = entry->d_name.name;
1806 unsigned int hash = entry->d_name.hash;
1807
1808 if (!inode) {
1809 __d_instantiate(entry, NULL);
1810 return NULL;
1811 }
1812
1813 hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
1814 /*
1815 * Don't need alias->d_lock here, because aliases with
1816 * d_parent == entry->d_parent are not subject to name or
1817 * parent changes, because the parent inode i_mutex is held.
1818 */
1819 if (alias->d_name.hash != hash)
1820 continue;
1821 if (alias->d_parent != entry->d_parent)
1822 continue;
1823 if (alias->d_name.len != len)
1824 continue;
1825 if (dentry_cmp(alias, name, len))
1826 continue;
1827 __dget(alias);
1828 return alias;
1829 }
1830
1831 __d_instantiate(entry, inode);
1832 return NULL;
1833}
1834
1835struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
1836{
1837 struct dentry *result;
1838
1839 BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
1840
1841 if (inode)
1842 spin_lock(&inode->i_lock);
1843 result = __d_instantiate_unique(entry, inode);
1844 if (inode)
1845 spin_unlock(&inode->i_lock);
1846
1847 if (!result) {
1848 security_d_instantiate(entry, inode);
1849 return NULL;
1850 }
1851
1852 BUG_ON(!d_unhashed(result));
1853 iput(inode);
1854 return result;
1855}
1856
1857EXPORT_SYMBOL(d_instantiate_unique);
1858
1859/**
1860 * d_instantiate_no_diralias - instantiate a non-aliased dentry 1785 * d_instantiate_no_diralias - instantiate a non-aliased dentry
1861 * @entry: dentry to complete 1786 * @entry: dentry to complete
1862 * @inode: inode to attach to this dentry 1787 * @inode: inode to attach to this dentry
@@ -2437,6 +2362,56 @@ void d_rehash(struct dentry * entry)
2437EXPORT_SYMBOL(d_rehash); 2362EXPORT_SYMBOL(d_rehash);
2438 2363
2439/** 2364/**
2365 * d_exact_alias - find and hash an exact unhashed alias
2366 * @entry: dentry to add
2367 * @inode: The inode to go with this dentry
2368 *
2369 * If an unhashed dentry with the same name/parent and desired
2370 * inode already exists, hash and return it. Otherwise, return
2371 * NULL.
2372 *
2373 * Parent directory should be locked.
2374 */
2375struct dentry *d_exact_alias(struct dentry *entry, struct inode *inode)
2376{
2377 struct dentry *alias;
2378 int len = entry->d_name.len;
2379 const char *name = entry->d_name.name;
2380 unsigned int hash = entry->d_name.hash;
2381
2382 spin_lock(&inode->i_lock);
2383 hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
2384 /*
2385 * Don't need alias->d_lock here, because aliases with
2386 * d_parent == entry->d_parent are not subject to name or
2387 * parent changes, because the parent inode i_mutex is held.
2388 */
2389 if (alias->d_name.hash != hash)
2390 continue;
2391 if (alias->d_parent != entry->d_parent)
2392 continue;
2393 if (alias->d_name.len != len)
2394 continue;
2395 if (dentry_cmp(alias, name, len))
2396 continue;
2397 spin_lock(&alias->d_lock);
2398 if (!d_unhashed(alias)) {
2399 spin_unlock(&alias->d_lock);
2400 alias = NULL;
2401 } else {
2402 __dget_dlock(alias);
2403 _d_rehash(alias);
2404 spin_unlock(&alias->d_lock);
2405 }
2406 spin_unlock(&inode->i_lock);
2407 return alias;
2408 }
2409 spin_unlock(&inode->i_lock);
2410 return NULL;
2411}
2412EXPORT_SYMBOL(d_exact_alias);
2413
2414/**
2440 * dentry_update_name_case - update case insensitive dentry with a new name 2415 * dentry_update_name_case - update case insensitive dentry with a new name
2441 * @dentry: dentry to be updated 2416 * @dentry: dentry to be updated
2442 * @name: new name 2417 * @name: new name