diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-08 12:44:17 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-14 00:17:20 -0400 |
commit | 668d0cd56ef7bc71be6dd8c081007221e09d9a86 (patch) | |
tree | e4e61bdd16fde1ad932861a23978601c2530f32a /fs/dcache.c | |
parent | e12a4e8a04a9ef84ba645379c56abad1a0ca9dbd (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.c | 125 |
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) | |||
1782 | EXPORT_SYMBOL(d_instantiate); | 1782 | EXPORT_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 | */ | ||
1800 | static 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 | |||
1835 | struct 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 | |||
1857 | EXPORT_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) | |||
2437 | EXPORT_SYMBOL(d_rehash); | 2362 | EXPORT_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 | */ | ||
2375 | struct 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 | } | ||
2412 | EXPORT_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 |