1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
8 #include <linux/kernel.h>
9 #include <linux/types.h>
13 static inline u16 upcase_unicode_char(const u16 *upcase, u16 chr)
19 return chr - ('a' - 'A');
27 * Thanks Kari Argillander <kari.argillander@gmail.com> for idea and implementation 'bothcase'
29 * Straight way to compare names:
31 * - If name equals and 'bothcases' then
33 * 'Straight way' code scans input names twice in worst case.
34 * Optimized code scans input names only once.
36 int ntfs_cmp_names(const __le16 *s1, size_t l1, const __le16 *s2, size_t l2,
37 const u16 *upcase, bool bothcase)
41 size_t len = min(l1, l2);
43 if (!bothcase && upcase)
46 for (; len; s1++, s2++, len--) {
47 diff1 = le16_to_cpu(*s1) - le16_to_cpu(*s2);
49 if (bothcase && upcase)
58 for (; len; s1++, s2++, len--) {
59 diff2 = upcase_unicode_char(upcase, le16_to_cpu(*s1)) -
60 upcase_unicode_char(upcase, le16_to_cpu(*s2));
66 return diff2 ? diff2 : diff1;
69 int ntfs_cmp_names_cpu(const struct cpu_str *uni1, const struct le_str *uni2,
70 const u16 *upcase, bool bothcase)
72 const u16 *s1 = uni1->name;
73 const __le16 *s2 = uni2->name;
74 size_t l1 = uni1->len;
75 size_t l2 = uni2->len;
76 size_t len = min(l1, l2);
80 if (!bothcase && upcase)
83 for (; len; s1++, s2++, len--) {
84 diff1 = *s1 - le16_to_cpu(*s2);
86 if (bothcase && upcase)
95 for (; len; s1++, s2++, len--) {
96 diff2 = upcase_unicode_char(upcase, *s1) -
97 upcase_unicode_char(upcase, le16_to_cpu(*s2));
103 return diff2 ? diff2 : diff1;
106 /* Helper function for ntfs_d_hash. */
107 unsigned long ntfs_names_hash(const u16 *name, size_t len, const u16 *upcase,
111 unsigned int c = upcase_unicode_char(upcase, *name++);
112 hash = partial_name_hash(c, hash);