Add new function to the libext2fs library, ext2fs_dirhash, which

calculates the hash of a filename for indexed directories.
This commit is contained in:
Theodore Ts'o 2002-03-11 15:04:45 -05:00
parent 708d3970e8
commit 52783e0ca7
7 changed files with 90 additions and 18 deletions

View File

@ -1,3 +1,8 @@
2002-03-11 Theodore Tso <tytso@mit.edu>
* htree.c (htree_dump_leaf_node): Use the ext2_dirhash function
instead of a local static function.
2002-03-08 Theodore Tso <tytso@mit.edu>
* Release of E2fsprogs 1.27

View File

@ -29,21 +29,6 @@ extern int optreset; /* defined by BSD, but not others */
static FILE *pager;
static unsigned dx_hack_hash (const char *name, int len)
{
__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
while (len--) {
__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
if (hash & 0x80000000) hash -= 0x7fffffff;
hash1 = hash0;
hash0 = hash;
}
return hash0;
}
#define dx_hash(s,n) (dx_hack_hash(s,n) << 1)
static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode,
blk_t blk, char *buf)
@ -54,6 +39,7 @@ static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
char name[EXT2_NAME_LEN];
char tmp[EXT2_NAME_LEN + 16];
blk_t pblk;
ext2_dirhash_t hash;
errcode = ext2fs_bmap(fs, ino, inode, buf, 0, blk, &pblk);
if (errcode) {
@ -82,8 +68,12 @@ static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
(dirent->name_len & 0xFF) : EXT2_NAME_LEN;
strncpy(name, dirent->name, thislen);
name[thislen] = '\0';
errcode = ext2fs_dirhash(0, name, thislen, &hash);
if (errcode)
com_err("htree_dump_leaf_node", errcode,
"while calculating hash");
sprintf(tmp, "%u 0x%08x (%d) %s ", dirent->inode,
dx_hash(name, thislen), dirent->rec_len, name);
hash, dirent->rec_len, name);
thislen = strlen(tmp);
if (col + thislen > 80) {
fprintf(pager, "\n");
@ -266,12 +256,19 @@ errout:
*/
void do_dx_hash(int argc, char *argv[])
{
ext2_dirhash_t hash;
errcode_t err;
if (argc != 2) {
com_err(argv[0], 0, "usage: dx_hash filename");
return;
}
printf("Hash of %s is 0x%0x\n", argv[1],
dx_hash(argv[1], strlen(argv[1])));
err = ext2fs_dirhash(0, argv[1], strlen(argv[1]), &hash);
if (err) {
com_err(argv[0], err, "while caclulating hash");
return;
}
printf("Hash of %s is 0x%0x\n", argv[1], hash);
}
/*

View File

@ -1,3 +1,10 @@
2002-03-11 Theodore Tso <tytso@mit.edu>
* ext2_err.et.in (EXT2_ET_DIRHASH_UNSUPP): New error code
* dirhash.c (ext2fs_dirhash): New function which calculates the
hash for a filename in an indexed directory.
2002-03-08 Theodore Tso <tytso@mit.edu>
* Release of E2fsprogs 1.27

View File

@ -30,6 +30,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
dblist.o \
dblist_dir.o \
dirblock.o \
dirhash.o \
dir_iterate.o \
expanddir.o \
ext_attr.o \
@ -79,6 +80,7 @@ SRCS= ext2_err.c \
$(srcdir)/dblist.c \
$(srcdir)/dblist_dir.c \
$(srcdir)/dirblock.c \
$(srcdir)/dirhash.c \
$(srcdir)/dir_iterate.c \
$(srcdir)/dupfs.c \
$(srcdir)/expanddir.c \

51
lib/ext2fs/dirhash.c Normal file
View File

@ -0,0 +1,51 @@
/*
* dirhash.c -- Calculate the hash of a directory entry
*
* Copyright (c) 2001 Daniel Phillips
*
* Copyright (c) 2002 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
* %End-Header%
*/
#include <stdio.h>
#include "ext2_fs.h"
#include "ext2fs.h"
static ext2_dirhash_t dx_hack_hash (const char *name, int len)
{
__u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
while (len--) {
__u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
if (hash & 0x80000000) hash -= 0x7fffffff;
hash1 = hash0;
hash0 = hash;
}
return hash0;
}
/*
* Returns the hash of a filename. If len is 0 and name is NULL, then
* this function can be used to test whether or not a hash version is
* supported.
*/
errcode_t ext2fs_dirhash(int version, const char *name, int len,
ext2_dirhash_t *ret_hash)
{
__u32 hash;
if (version == 0)
hash = dx_hack_hash(name, len);
else {
*ret_hash = 0;
return EXT2_ET_DIRHASH_UNSUPP;
}
*ret_hash = hash;
return 0;
}

View File

@ -275,5 +275,8 @@ ec EXT2_ET_LOAD_EXT_JOURNAL,
ec EXT2_ET_NO_JOURNAL,
"Journal not found"
ec EXT2_ET_DIRHASH_UNSUPP,
"Directory hash unsupported"
end

View File

@ -65,6 +65,7 @@ typedef __u32 blk_t;
typedef __u32 dgrp_t;
typedef __u32 ext2_off_t;
typedef __s64 e2_blkcnt_t;
typedef __u32 ext2_dirhash_t;
#if EXT2_FLAT_INCLUDES
#include "com_err.h"
@ -406,6 +407,7 @@ typedef struct ext2_icount *ext2_icount_t;
#define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
EXT2_FEATURE_COMPAT_DIR_INDEX|\
EXT2_FEATURE_COMPAT_EXT_ATTR)
/* This #ifdef is temporary until compression is fully supported */
@ -599,6 +601,11 @@ extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
void *buf);
/* dirhash.c */
extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
ext2_dirhash_t *ret_hash);
/* dir_iterate.c */
extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
ext2_ino_t dir,