fs/ext4/hash.c

Source file repositories/reference/linux-study-clean/fs/ext4/hash.c

File Facts

System
Linux kernel
Corpus path
fs/ext4/hash.c
Extension
.c
Size
7882 bytes
Lines
348
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (hinfo->seed[i]) {
				memcpy(buf, hinfo->seed, sizeof(buf));
				break;
			}
		}
	}

	switch (hinfo->hash_version) {
	case DX_HASH_LEGACY_UNSIGNED:
		hash = dx_hack_hash_unsigned(name, len);
		break;
	case DX_HASH_LEGACY:
		hash = dx_hack_hash_signed(name, len);
		break;
	case DX_HASH_HALF_MD4_UNSIGNED:
		use_unsigned = true;
		fallthrough;
	case DX_HASH_HALF_MD4:
		p = name;
		while (len > 0) {
			if (use_unsigned)
				str2hashbuf_unsigned(p, len, in, 8);
			else
				str2hashbuf_signed(p, len, in, 8);
			half_md4_transform(buf, in);
			len -= 32;
			p += 32;
		}
		minor_hash = buf[2];
		hash = buf[1];
		break;
	case DX_HASH_TEA_UNSIGNED:
		use_unsigned = true;
		fallthrough;
	case DX_HASH_TEA:
		p = name;
		while (len > 0) {
			if (use_unsigned)
				str2hashbuf_unsigned(p, len, in, 4);
			else
				str2hashbuf_signed(p, len, in, 4);
			TEA_transform(buf, in);
			len -= 16;
			p += 16;
		}
		hash = buf[0];
		minor_hash = buf[1];
		break;
	case DX_HASH_SIPHASH:
	{
		struct qstr qname = QSTR_INIT(name, len);
		__u64	combined_hash;

		if (fscrypt_has_encryption_key(dir)) {
			combined_hash = fscrypt_fname_siphash(dir, &qname);
		} else {
			ext4_warning_inode(dir, "Siphash requires key");
			return -EINVAL;
		}

		hash = (__u32)(combined_hash >> 32);
		minor_hash = (__u32)combined_hash;
		break;
	}
	default:
		hinfo->hash = 0;
		hinfo->minor_hash = 0;
		ext4_warning(dir->i_sb,
			     "invalid/unsupported hash tree version %u",
			     hinfo->hash_version);
		return -EINVAL;
	}
	hash = hash & ~1;
	if (hash == (EXT4_HTREE_EOF_32BIT << 1))
		hash = (EXT4_HTREE_EOF_32BIT - 1) << 1;
	hinfo->hash = hash;
	hinfo->minor_hash = minor_hash;
	return 0;
}

int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
		   struct dx_hash_info *hinfo)
{
#if IS_ENABLED(CONFIG_UNICODE)
	const struct unicode_map *um = dir->i_sb->s_encoding;
	int r, dlen;
	unsigned char *buff;
	struct qstr qstr = {.name = name, .len = len };

	if (len && IS_CASEFOLDED(dir) &&

Annotation

Implementation Notes