mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	This commit adds mount option and additional functions. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
		
			
				
	
	
		
			116 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0
 | 
						|
/*
 | 
						|
 *
 | 
						|
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/kernel.h>
 | 
						|
#include <linux/types.h>
 | 
						|
 | 
						|
#include "ntfs_fs.h"
 | 
						|
 | 
						|
static inline u16 upcase_unicode_char(const u16 *upcase, u16 chr)
 | 
						|
{
 | 
						|
	if (chr < 'a')
 | 
						|
		return chr;
 | 
						|
 | 
						|
	if (chr <= 'z')
 | 
						|
		return chr - ('a' - 'A');
 | 
						|
 | 
						|
	return upcase[chr];
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * ntfs_cmp_names
 | 
						|
 *
 | 
						|
 * Thanks Kari Argillander <kari.argillander@gmail.com> for idea and implementation 'bothcase'
 | 
						|
 *
 | 
						|
 * Straight way to compare names:
 | 
						|
 * - Case insensitive
 | 
						|
 * - If name equals and 'bothcases' then
 | 
						|
 * - Case sensitive
 | 
						|
 * 'Straight way' code scans input names twice in worst case.
 | 
						|
 * Optimized code scans input names only once.
 | 
						|
 */
 | 
						|
int ntfs_cmp_names(const __le16 *s1, size_t l1, const __le16 *s2, size_t l2,
 | 
						|
		   const u16 *upcase, bool bothcase)
 | 
						|
{
 | 
						|
	int diff1 = 0;
 | 
						|
	int diff2;
 | 
						|
	size_t len = min(l1, l2);
 | 
						|
 | 
						|
	if (!bothcase && upcase)
 | 
						|
		goto case_insentive;
 | 
						|
 | 
						|
	for (; len; s1++, s2++, len--) {
 | 
						|
		diff1 = le16_to_cpu(*s1) - le16_to_cpu(*s2);
 | 
						|
		if (diff1) {
 | 
						|
			if (bothcase && upcase)
 | 
						|
				goto case_insentive;
 | 
						|
 | 
						|
			return diff1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return l1 - l2;
 | 
						|
 | 
						|
case_insentive:
 | 
						|
	for (; len; s1++, s2++, len--) {
 | 
						|
		diff2 = upcase_unicode_char(upcase, le16_to_cpu(*s1)) -
 | 
						|
			upcase_unicode_char(upcase, le16_to_cpu(*s2));
 | 
						|
		if (diff2)
 | 
						|
			return diff2;
 | 
						|
	}
 | 
						|
 | 
						|
	diff2 = l1 - l2;
 | 
						|
	return diff2 ? diff2 : diff1;
 | 
						|
}
 | 
						|
 | 
						|
int ntfs_cmp_names_cpu(const struct cpu_str *uni1, const struct le_str *uni2,
 | 
						|
		       const u16 *upcase, bool bothcase)
 | 
						|
{
 | 
						|
	const u16 *s1 = uni1->name;
 | 
						|
	const __le16 *s2 = uni2->name;
 | 
						|
	size_t l1 = uni1->len;
 | 
						|
	size_t l2 = uni2->len;
 | 
						|
	size_t len = min(l1, l2);
 | 
						|
	int diff1 = 0;
 | 
						|
	int diff2;
 | 
						|
 | 
						|
	if (!bothcase && upcase)
 | 
						|
		goto case_insentive;
 | 
						|
 | 
						|
	for (; len; s1++, s2++, len--) {
 | 
						|
		diff1 = *s1 - le16_to_cpu(*s2);
 | 
						|
		if (diff1) {
 | 
						|
			if (bothcase && upcase)
 | 
						|
				goto case_insentive;
 | 
						|
 | 
						|
			return diff1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return l1 - l2;
 | 
						|
 | 
						|
case_insentive:
 | 
						|
	for (; len; s1++, s2++, len--) {
 | 
						|
		diff2 = upcase_unicode_char(upcase, *s1) -
 | 
						|
			upcase_unicode_char(upcase, le16_to_cpu(*s2));
 | 
						|
		if (diff2)
 | 
						|
			return diff2;
 | 
						|
	}
 | 
						|
 | 
						|
	diff2 = l1 - l2;
 | 
						|
	return diff2 ? diff2 : diff1;
 | 
						|
}
 | 
						|
 | 
						|
/* Helper function for ntfs_d_hash. */
 | 
						|
unsigned long ntfs_names_hash(const u16 *name, size_t len, const u16 *upcase,
 | 
						|
			      unsigned long hash)
 | 
						|
{
 | 
						|
	while (len--) {
 | 
						|
		unsigned int c = upcase_unicode_char(upcase, *name++);
 | 
						|
		hash = partial_name_hash(c, hash);
 | 
						|
	}
 | 
						|
 | 
						|
	return hash;
 | 
						|
}
 |