aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c19
-rw-r--r--include/linux/dcache.h1
2 files changed, 11 insertions, 9 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 229235862e50..2be5120b81b3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1669,13 +1669,14 @@ EXPORT_SYMBOL(full_name_hash);
1669 1669
1670/* 1670/*
1671 * Calculate the length and hash of the path component, and 1671 * Calculate the length and hash of the path component, and
1672 * return the length of the component; 1672 * fill in the qstr. return the "len" as the result.
1673 */ 1673 */
1674static inline unsigned long hash_name(const char *name, unsigned int *hashp) 1674static inline unsigned long hash_name(const char *name, struct qstr *res)
1675{ 1675{
1676 unsigned long a, b, adata, bdata, mask, hash, len; 1676 unsigned long a, b, adata, bdata, mask, hash, len;
1677 const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; 1677 const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
1678 1678
1679 res->name = name;
1679 hash = a = 0; 1680 hash = a = 0;
1680 len = -sizeof(unsigned long); 1681 len = -sizeof(unsigned long);
1681 do { 1682 do {
@@ -1691,9 +1692,10 @@ static inline unsigned long hash_name(const char *name, unsigned int *hashp)
1691 mask = create_zero_mask(adata | bdata); 1692 mask = create_zero_mask(adata | bdata);
1692 1693
1693 hash += a & zero_bytemask(mask); 1694 hash += a & zero_bytemask(mask);
1694 *hashp = fold_hash(hash); 1695 len += find_zero(mask);
1696 res->hash_len = hashlen_create(fold_hash(hash), len);
1695 1697
1696 return len + find_zero(mask); 1698 return len;
1697} 1699}
1698 1700
1699#else 1701#else
@@ -1711,18 +1713,19 @@ EXPORT_SYMBOL(full_name_hash);
1711 * We know there's a real path component here of at least 1713 * We know there's a real path component here of at least
1712 * one character. 1714 * one character.
1713 */ 1715 */
1714static inline unsigned long hash_name(const char *name, unsigned int *hashp) 1716static inline long hash_name(const char *name, struct qstr *res)
1715{ 1717{
1716 unsigned long hash = init_name_hash(); 1718 unsigned long hash = init_name_hash();
1717 unsigned long len = 0, c; 1719 unsigned long len = 0, c;
1718 1720
1721 res->name = name;
1719 c = (unsigned char)*name; 1722 c = (unsigned char)*name;
1720 do { 1723 do {
1721 len++; 1724 len++;
1722 hash = partial_name_hash(c, hash); 1725 hash = partial_name_hash(c, hash);
1723 c = (unsigned char)name[len]; 1726 c = (unsigned char)name[len];
1724 } while (c && c != '/'); 1727 } while (c && c != '/');
1725 *hashp = end_name_hash(hash); 1728 res->hash_len = hashlen_create(end_name_hash(hash), len);
1726 return len; 1729 return len;
1727} 1730}
1728 1731
@@ -1756,9 +1759,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1756 if (err) 1759 if (err)
1757 break; 1760 break;
1758 1761
1759 len = hash_name(name, &this.hash); 1762 len = hash_name(name, &this);
1760 this.name = name;
1761 this.len = len;
1762 1763
1763 type = LAST_NORM; 1764 type = LAST_NORM;
1764 if (name[0] == '.') switch (len) { 1765 if (name[0] == '.') switch (len) {
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index e4ae2ad48d07..75a227cc7ce2 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -55,6 +55,7 @@ struct qstr {
55#define QSTR_INIT(n,l) { { { .len = l } }, .name = n } 55#define QSTR_INIT(n,l) { { { .len = l } }, .name = n }
56#define hashlen_hash(hashlen) ((u32) (hashlen)) 56#define hashlen_hash(hashlen) ((u32) (hashlen))
57#define hashlen_len(hashlen) ((u32)((hashlen) >> 32)) 57#define hashlen_len(hashlen) ((u32)((hashlen) >> 32))
58#define hashlen_create(hash,len) (((u64)(len)<<32)|(u32)(hash))
58 59
59struct dentry_stat_t { 60struct dentry_stat_t {
60 long nr_dentry; 61 long nr_dentry;