diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-08 14:17:44 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-14 09:15:26 -0400 |
commit | 5a202bcd75bbd2397136397961babbd8463416af (patch) | |
tree | 4a973df44ef169e66ee2aa5eb6c6b7ed69059509 /fs/namei.c | |
parent | 6a96ba54418be740303765c0f52be028573cb99a (diff) |
sanitize pathname component hash calculation
Lift it to lookup_one_len() and link_path_walk() resp. into the
same place where we calculated default hash function of the same
name.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 42 |
1 files changed, 19 insertions, 23 deletions
diff --git a/fs/namei.c b/fs/namei.c index f6f3ef47bc74..d1a5dfeaf999 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1217,16 +1217,6 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
1217 | int err; | 1217 | int err; |
1218 | 1218 | ||
1219 | /* | 1219 | /* |
1220 | * See if the low-level filesystem might want | ||
1221 | * to use its own hash.. | ||
1222 | */ | ||
1223 | if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { | ||
1224 | err = parent->d_op->d_hash(parent, nd->inode, name); | ||
1225 | if (err < 0) | ||
1226 | return err; | ||
1227 | } | ||
1228 | |||
1229 | /* | ||
1230 | * Rename seqlock is not required here because in the off chance | 1220 | * Rename seqlock is not required here because in the off chance |
1231 | * of a false negative due to a concurrent rename, we're going to | 1221 | * of a false negative due to a concurrent rename, we're going to |
1232 | * do the non-racy lookup, below. | 1222 | * do the non-racy lookup, below. |
@@ -1414,8 +1404,16 @@ static int link_path_walk(const char *name, struct nameidata *nd) | |||
1414 | case 1: | 1404 | case 1: |
1415 | type = LAST_DOT; | 1405 | type = LAST_DOT; |
1416 | } | 1406 | } |
1417 | if (likely(type == LAST_NORM)) | 1407 | if (likely(type == LAST_NORM)) { |
1408 | struct dentry *parent = nd->path.dentry; | ||
1418 | nd->flags &= ~LOOKUP_JUMPED; | 1409 | nd->flags &= ~LOOKUP_JUMPED; |
1410 | if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { | ||
1411 | err = parent->d_op->d_hash(parent, nd->inode, | ||
1412 | &this); | ||
1413 | if (err < 0) | ||
1414 | break; | ||
1415 | } | ||
1416 | } | ||
1419 | 1417 | ||
1420 | /* remove trailing slashes? */ | 1418 | /* remove trailing slashes? */ |
1421 | if (!c) | 1419 | if (!c) |
@@ -1723,17 +1721,6 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1723 | return ERR_PTR(err); | 1721 | return ERR_PTR(err); |
1724 | 1722 | ||
1725 | /* | 1723 | /* |
1726 | * See if the low-level filesystem might want | ||
1727 | * to use its own hash.. | ||
1728 | */ | ||
1729 | if (base->d_flags & DCACHE_OP_HASH) { | ||
1730 | err = base->d_op->d_hash(base, inode, name); | ||
1731 | dentry = ERR_PTR(err); | ||
1732 | if (err < 0) | ||
1733 | goto out; | ||
1734 | } | ||
1735 | |||
1736 | /* | ||
1737 | * Don't bother with __d_lookup: callers are for creat as | 1724 | * Don't bother with __d_lookup: callers are for creat as |
1738 | * well as unlink, so a lot of the time it would cost | 1725 | * well as unlink, so a lot of the time it would cost |
1739 | * a double lookup. | 1726 | * a double lookup. |
@@ -1745,7 +1732,7 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1745 | 1732 | ||
1746 | if (!dentry) | 1733 | if (!dentry) |
1747 | dentry = d_alloc_and_lookup(base, name, nd); | 1734 | dentry = d_alloc_and_lookup(base, name, nd); |
1748 | out: | 1735 | |
1749 | return dentry; | 1736 | return dentry; |
1750 | } | 1737 | } |
1751 | 1738 | ||
@@ -1791,6 +1778,15 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) | |||
1791 | hash = partial_name_hash(c, hash); | 1778 | hash = partial_name_hash(c, hash); |
1792 | } | 1779 | } |
1793 | this.hash = end_name_hash(hash); | 1780 | this.hash = end_name_hash(hash); |
1781 | /* | ||
1782 | * See if the low-level filesystem might want | ||
1783 | * to use its own hash.. | ||
1784 | */ | ||
1785 | if (base->d_flags & DCACHE_OP_HASH) { | ||
1786 | int err = base->d_op->d_hash(base, base->d_inode, &this); | ||
1787 | if (err < 0) | ||
1788 | return ERR_PTR(err); | ||
1789 | } | ||
1794 | 1790 | ||
1795 | return __lookup_hash(&this, base, NULL); | 1791 | return __lookup_hash(&this, base, NULL); |
1796 | } | 1792 | } |