aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c80
1 files changed, 21 insertions, 59 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 19153a0a810c..68220dd0c135 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1358,6 +1358,7 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
1358 WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH | 1358 WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH |
1359 DCACHE_OP_COMPARE | 1359 DCACHE_OP_COMPARE |
1360 DCACHE_OP_REVALIDATE | 1360 DCACHE_OP_REVALIDATE |
1361 DCACHE_OP_WEAK_REVALIDATE |
1361 DCACHE_OP_DELETE )); 1362 DCACHE_OP_DELETE ));
1362 dentry->d_op = op; 1363 dentry->d_op = op;
1363 if (!op) 1364 if (!op)
@@ -1368,6 +1369,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
1368 dentry->d_flags |= DCACHE_OP_COMPARE; 1369 dentry->d_flags |= DCACHE_OP_COMPARE;
1369 if (op->d_revalidate) 1370 if (op->d_revalidate)
1370 dentry->d_flags |= DCACHE_OP_REVALIDATE; 1371 dentry->d_flags |= DCACHE_OP_REVALIDATE;
1372 if (op->d_weak_revalidate)
1373 dentry->d_flags |= DCACHE_OP_WEAK_REVALIDATE;
1371 if (op->d_delete) 1374 if (op->d_delete)
1372 dentry->d_flags |= DCACHE_OP_DELETE; 1375 dentry->d_flags |= DCACHE_OP_DELETE;
1373 if (op->d_prune) 1376 if (op->d_prune)
@@ -1672,7 +1675,6 @@ EXPORT_SYMBOL(d_splice_alias);
1672struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, 1675struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1673 struct qstr *name) 1676 struct qstr *name)
1674{ 1677{
1675 int error;
1676 struct dentry *found; 1678 struct dentry *found;
1677 struct dentry *new; 1679 struct dentry *new;
1678 1680
@@ -1681,10 +1683,12 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1681 * if not go ahead and create it now. 1683 * if not go ahead and create it now.
1682 */ 1684 */
1683 found = d_hash_and_lookup(dentry->d_parent, name); 1685 found = d_hash_and_lookup(dentry->d_parent, name);
1686 if (unlikely(IS_ERR(found)))
1687 goto err_out;
1684 if (!found) { 1688 if (!found) {
1685 new = d_alloc(dentry->d_parent, name); 1689 new = d_alloc(dentry->d_parent, name);
1686 if (!new) { 1690 if (!new) {
1687 error = -ENOMEM; 1691 found = ERR_PTR(-ENOMEM);
1688 goto err_out; 1692 goto err_out;
1689 } 1693 }
1690 1694
@@ -1725,7 +1729,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1725 1729
1726err_out: 1730err_out:
1727 iput(inode); 1731 iput(inode);
1728 return ERR_PTR(error); 1732 return found;
1729} 1733}
1730EXPORT_SYMBOL(d_add_ci); 1734EXPORT_SYMBOL(d_add_ci);
1731 1735
@@ -1889,7 +1893,7 @@ seqretry:
1889 * dentry is returned. The caller must use dput to free the entry when it has 1893 * dentry is returned. The caller must use dput to free the entry when it has
1890 * finished using it. %NULL is returned if the dentry does not exist. 1894 * finished using it. %NULL is returned if the dentry does not exist.
1891 */ 1895 */
1892struct dentry *d_lookup(struct dentry *parent, struct qstr *name) 1896struct dentry *d_lookup(const struct dentry *parent, const struct qstr *name)
1893{ 1897{
1894 struct dentry *dentry; 1898 struct dentry *dentry;
1895 unsigned seq; 1899 unsigned seq;
@@ -1919,7 +1923,7 @@ EXPORT_SYMBOL(d_lookup);
1919 * 1923 *
1920 * __d_lookup callers must be commented. 1924 * __d_lookup callers must be commented.
1921 */ 1925 */
1922struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) 1926struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name)
1923{ 1927{
1924 unsigned int len = name->len; 1928 unsigned int len = name->len;
1925 unsigned int hash = name->hash; 1929 unsigned int hash = name->hash;
@@ -1997,12 +2001,10 @@ next:
1997 * @dir: Directory to search in 2001 * @dir: Directory to search in
1998 * @name: qstr of name we wish to find 2002 * @name: qstr of name we wish to find
1999 * 2003 *
2000 * On hash failure or on lookup failure NULL is returned. 2004 * On lookup failure NULL is returned; on bad name - ERR_PTR(-error)
2001 */ 2005 */
2002struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name) 2006struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
2003{ 2007{
2004 struct dentry *dentry = NULL;
2005
2006 /* 2008 /*
2007 * Check for a fs-specific hash function. Note that we must 2009 * Check for a fs-specific hash function. Note that we must
2008 * calculate the standard hash first, as the d_op->d_hash() 2010 * calculate the standard hash first, as the d_op->d_hash()
@@ -2010,13 +2012,13 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
2010 */ 2012 */
2011 name->hash = full_name_hash(name->name, name->len); 2013 name->hash = full_name_hash(name->name, name->len);
2012 if (dir->d_flags & DCACHE_OP_HASH) { 2014 if (dir->d_flags & DCACHE_OP_HASH) {
2013 if (dir->d_op->d_hash(dir, dir->d_inode, name) < 0) 2015 int err = dir->d_op->d_hash(dir, dir->d_inode, name);
2014 goto out; 2016 if (unlikely(err < 0))
2017 return ERR_PTR(err);
2015 } 2018 }
2016 dentry = d_lookup(dir, name); 2019 return d_lookup(dir, name);
2017out:
2018 return dentry;
2019} 2020}
2021EXPORT_SYMBOL(d_hash_and_lookup);
2020 2022
2021/** 2023/**
2022 * d_validate - verify dentry provided from insecure source (deprecated) 2024 * d_validate - verify dentry provided from insecure source (deprecated)
@@ -2394,7 +2396,7 @@ out_err:
2394 */ 2396 */
2395static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon) 2397static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
2396{ 2398{
2397 struct dentry *dparent, *aparent; 2399 struct dentry *dparent;
2398 2400
2399 dentry_lock_for_move(anon, dentry); 2401 dentry_lock_for_move(anon, dentry);
2400 2402
@@ -2402,24 +2404,15 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
2402 write_seqcount_begin(&anon->d_seq); 2404 write_seqcount_begin(&anon->d_seq);
2403 2405
2404 dparent = dentry->d_parent; 2406 dparent = dentry->d_parent;
2405 aparent = anon->d_parent;
2406 2407
2407 switch_names(dentry, anon); 2408 switch_names(dentry, anon);
2408 swap(dentry->d_name.hash, anon->d_name.hash); 2409 swap(dentry->d_name.hash, anon->d_name.hash);
2409 2410
2410 dentry->d_parent = (aparent == anon) ? dentry : aparent; 2411 dentry->d_parent = dentry;
2411 list_del(&dentry->d_u.d_child); 2412 list_del_init(&dentry->d_u.d_child);
2412 if (!IS_ROOT(dentry)) 2413 anon->d_parent = dparent;
2413 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2414 else
2415 INIT_LIST_HEAD(&dentry->d_u.d_child);
2416
2417 anon->d_parent = (dparent == dentry) ? anon : dparent;
2418 list_del(&anon->d_u.d_child); 2414 list_del(&anon->d_u.d_child);
2419 if (!IS_ROOT(anon)) 2415 list_add(&anon->d_u.d_child, &dparent->d_subdirs);
2420 list_add(&anon->d_u.d_child, &anon->d_parent->d_subdirs);
2421 else
2422 INIT_LIST_HEAD(&anon->d_u.d_child);
2423 2416
2424 write_seqcount_end(&dentry->d_seq); 2417 write_seqcount_end(&dentry->d_seq);
2425 write_seqcount_end(&anon->d_seq); 2418 write_seqcount_end(&anon->d_seq);
@@ -2722,37 +2715,6 @@ char *d_path(const struct path *path, char *buf, int buflen)
2722} 2715}
2723EXPORT_SYMBOL(d_path); 2716EXPORT_SYMBOL(d_path);
2724 2717
2725/**
2726 * d_path_with_unreachable - return the path of a dentry
2727 * @path: path to report
2728 * @buf: buffer to return value in
2729 * @buflen: buffer length
2730 *
2731 * The difference from d_path() is that this prepends "(unreachable)"
2732 * to paths which are unreachable from the current process' root.
2733 */
2734char *d_path_with_unreachable(const struct path *path, char *buf, int buflen)
2735{
2736 char *res = buf + buflen;
2737 struct path root;
2738 int error;
2739
2740 if (path->dentry->d_op && path->dentry->d_op->d_dname)
2741 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
2742
2743 get_fs_root(current->fs, &root);
2744 write_seqlock(&rename_lock);
2745 error = path_with_deleted(path, &root, &res, &buflen);
2746 if (error > 0)
2747 error = prepend_unreachable(&res, &buflen);
2748 write_sequnlock(&rename_lock);
2749 path_put(&root);
2750 if (error)
2751 res = ERR_PTR(error);
2752
2753 return res;
2754}
2755
2756/* 2718/*
2757 * Helper function for dentry_operations.d_dname() members 2719 * Helper function for dentry_operations.d_dname() members
2758 */ 2720 */
@@ -3035,7 +2997,7 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name)
3035 ino_t ino = 0; 2997 ino_t ino = 0;
3036 2998
3037 dentry = d_hash_and_lookup(dir, name); 2999 dentry = d_hash_and_lookup(dir, name);
3038 if (dentry) { 3000 if (!IS_ERR_OR_NULL(dentry)) {
3039 if (dentry->d_inode) 3001 if (dentry->d_inode)
3040 ino = dentry->d_inode->i_ino; 3002 ino = dentry->d_inode->i_ino;
3041 dput(dentry); 3003 dput(dentry);