| @@ -1822,19 +1822,20 @@ static inline unsigned long mix_hash(unsigned long hash) · 1821 unmodified lines |
| 1822 | 1822 | |
| 1823 | 1823 | #endif |
| 1824 | 1824 | |
| 1825 | | −unsigned int full_name_hash(const unsigned char *name, unsigned int len) |
| 1825 | +/* Return the hash of a string of known length */ |
| 1826 | +unsigned int full_name_hash(const char *name, unsigned int len) |
| 1826 | 1827 | { |
| 1827 | 1828 | unsigned long a, hash = 0; |
| 1828 | 1829 | |
| 1829 | 1830 | for (;;) { |
| 1831 | + if (!len) |
| 1832 | + goto done; |
| 1830 | 1833 | a = load_unaligned_zeropad(name); |
| 1831 | 1834 | if (len < sizeof(unsigned long)) |
| 1832 | 1835 | break; |
| 1833 | 1836 | hash = mix_hash(hash + a); |
| 1834 | 1837 | name += sizeof(unsigned long); |
| 1835 | 1838 | len -= sizeof(unsigned long); |
| 1836 | | − if (!len) |
| 1837 | | − goto done; |
| 1838 | 1839 | } |
| 1839 | 1840 | hash += a & bytemask_from_count(len); |
| 1840 | 1841 | done: |
| @@ -1842,6 +1843,29 @@ done: · 1 unmodified line |
| 1842 | 1843 | } |
| 1843 | 1844 | EXPORT_SYMBOL(full_name_hash); |
| 1844 | 1845 | |
| 1846 | +/* Return the "hash_len" (hash and length) of a null-terminated string */ |
| 1847 | +u64 hashlen_string(const char *name) |
| 1848 | +{ |
| 1849 | + unsigned long a, adata, mask, hash, len; |
| 1850 | + const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; |
| 1851 | + |
| 1852 | + hash = a = 0; |
| 1853 | + len = -sizeof(unsigned long); |
| 1854 | + do { |
| 1855 | + hash = mix_hash(hash + a); |
| 1856 | + len += sizeof(unsigned long); |
| 1857 | + a = load_unaligned_zeropad(name+len); |
| 1858 | + } while (!has_zero(a, &adata, &constants)); |
| 1859 | + |
| 1860 | + adata = prep_zero_mask(a, adata, &constants); |
| 1861 | + mask = create_zero_mask(adata); |
| 1862 | + hash += a & zero_bytemask(mask); |
| 1863 | + len += find_zero(mask); |
| 1864 | + |
| 1865 | + return hashlen_create(fold_hash(hash), len); |
| 1866 | +} |
| 1867 | +EXPORT_SYMBOL(hashlen_string); |
| 1868 | + |
| 1845 | 1869 | /* |
| 1846 | 1870 | * Calculate the length and hash of the path component, and |
| 1847 | 1871 | * return the "hash_len" as the result. |
| @@ -1872,15 +1896,32 @@ static inline u64 hash_name(const char *name) · 24 unmodified lines |
| 1872 | 1896 | |
| 1873 | 1897 | #else |
| 1874 | 1898 | |
| 1875 | | −unsigned int full_name_hash(const unsigned char *name, unsigned int len) |
| 1899 | +/* Return the hash of a string of known length */ |
| 1900 | +unsigned int full_name_hash(const char *name, unsigned int len) |
| 1876 | 1901 | { |
| 1877 | 1902 | unsigned long hash = init_name_hash(); |
| 1878 | 1903 | while (len--) |
| 1879 | | − hash = partial_name_hash(*name++, hash); |
| 1904 | + hash = partial_name_hash((unsigned char)*name++, hash); |
| 1880 | 1905 | return end_name_hash(hash); |
| 1881 | 1906 | } |
| 1882 | 1907 | EXPORT_SYMBOL(full_name_hash); |
| 1883 | 1908 | |
| 1909 | +/* Return the "hash_len" (hash and length) of a null-terminated string */ |
| 1910 | +u64 hash_string(const char *name) |
| 1911 | +{ |
| 1912 | + unsigned long hash = init_name_hash(); |
| 1913 | + unsigned long len = 0, c; |
| 1914 | + |
| 1915 | + c = (unsigned char)*name; |
| 1916 | + do { |
| 1917 | + len++; |
| 1918 | + hash = partial_name_hash(c, hash); |
| 1919 | + c = (unsigned char)name[len]; |
| 1920 | + } while (c); |
| 1921 | + return hashlen_create(end_name_hash(hash), len); |
| 1922 | +} |
| 1923 | +EXPORT_SYMBOL(hash_string); |
| 1924 | + |
| 1884 | 1925 | /* |
| 1885 | 1926 | * We know there's a real path component here of at least |
| 1886 | 1927 | * one character. |