Re: [patch 2/2] HFS+: Add custom dentry hash and comparison operations
On Mon, 25 Jun 2007 14:17:19 +0200 (CEST) Roman Zippel <[EMAIL PROTECTED]> wrote: > +/* > + * Hash a string to an integer as appropriate for the HFS+ filesystem. > + * Composed unicode characters are decomposed and case-folding is performed > + * if the appropriate bits are (un)set on the superblock. > + */ > +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) > +{ > + struct super_block *sb = dentry->d_sb; > + const char *astr; > + const u16 *dstr; > + int casefold, decompose, size, dsize, len; > + unsigned long hash; > + wchar_t c; > + u16 c2; > + > + casefold = (HFSPLUS_SB(sb).flags & HFSPLUS_SB_CASEFOLD); > + decompose = !(HFSPLUS_SB(sb).flags & HFSPLUS_SB_NODECOMPOSE); > + hash = init_name_hash(); > + astr = str->name; > + len = str->len; > + while (len > 0) { > + size = asc2unichar(sb, astr, len, ); > + astr += size; > + len -= size; > + > + if (decompose && (dstr = decompose_unichar(c, ))) { > + do { > + c2 = *dstr++; > + if (!casefold || (c2 = case_fold(c2))) > + hash = partial_name_hash(c2, hash); > + } while (--dsize > 0); Are you really sure that we cannot start this loop with dsize==0? This isn't obviously true to these bleary eyes. > + } else { > + c2 = c; > + if (!casefold || (c2 = case_fold(c2))) > + hash = partial_name_hash(c2, hash); > + } > + } > + str->hash = end_name_hash(hash); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 2/2] HFS+: Add custom dentry hash and comparison operations
Hi, On Wed, 20 Jun 2007, Duane Griffin wrote: > Add custom dentry hash and comparison operations for HFS+ filesystems > that are case-insensitive and/or do automatic unicode decomposition. > The new operations reuse the existing HFS+ ASCII to unicode conversion, > unicode decomposition and case folding functionality. The changes in the previous patch required a few changes in this patch as well, but there were also a few small problems. The case condition wasn't quite correct and some characters have to be ignored during compare/hash. bye, Roman From: Duane Griffin <[EMAIL PROTECTED]> Add custom dentry hash and comparison operations for HFS+ filesystems that are case-insensitive and/or do automatic unicode decomposition. The new operations reuse the existing HFS+ ASCII to unicode conversion, unicode decomposition and case folding functionality. Signed-off-by: Duane Griffin <[EMAIL PROTECTED]> Signed-off-by: Roman Zippel <[EMAIL PROTECTED]> --- fs/hfsplus/btree.c |4 + fs/hfsplus/dir.c|2 fs/hfsplus/hfsplus_fs.h |4 + fs/hfsplus/inode.c |5 + fs/hfsplus/super.c |1 fs/hfsplus/unicode.c| 123 6 files changed, 138 insertions(+), 1 deletion(-) Index: linux-2.6/fs/hfsplus/dir.c === --- linux-2.6.orig/fs/hfsplus/dir.c 2007-04-26 19:45:57.0 +0200 +++ linux-2.6/fs/hfsplus/dir.c 2007-06-25 13:39:46.0 +0200 @@ -36,6 +36,8 @@ static struct dentry *hfsplus_lookup(str u16 type; sb = dir->i_sb; + + dentry->d_op = _dentry_operations; dentry->d_fsdata = NULL; hfs_find_init(HFSPLUS_SB(sb).cat_tree, ); hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, >d_name); Index: linux-2.6/fs/hfsplus/hfsplus_fs.h === --- linux-2.6.orig/fs/hfsplus/hfsplus_fs.h 2007-04-26 19:45:57.0 +0200 +++ linux-2.6/fs/hfsplus/hfsplus_fs.h 2007-06-25 12:59:16.0 +0200 @@ -150,6 +150,7 @@ struct hfsplus_sb_info { #define HFSPLUS_SB_NODECOMPOSE 0x0002 #define HFSPLUS_SB_FORCE 0x0004 #define HFSPLUS_SB_HFSX0x0008 +#define HFSPLUS_SB_CASEFOLD0x0010 struct hfsplus_inode_info { @@ -321,6 +322,7 @@ void hfsplus_file_truncate(struct inode /* inode.c */ extern const struct address_space_operations hfsplus_aops; extern const struct address_space_operations hfsplus_btree_aops; +extern struct dentry_operations hfsplus_dentry_operations; void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *); void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *); @@ -353,6 +355,8 @@ int hfsplus_strcasecmp(const struct hfsp int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); +int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2); /* wrapper.c */ int hfsplus_read_wrapper(struct super_block *); Index: linux-2.6/fs/hfsplus/inode.c === --- linux-2.6.orig/fs/hfsplus/inode.c 2007-04-26 19:45:57.0 +0200 +++ linux-2.6/fs/hfsplus/inode.c2007-06-25 13:52:54.0 +0200 @@ -130,6 +130,11 @@ const struct address_space_operations hf .writepages = hfsplus_writepages, }; +struct dentry_operations hfsplus_dentry_operations = { + .d_hash = hfsplus_hash_dentry, + .d_compare= hfsplus_compare_dentry, +}; + static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { Index: linux-2.6/fs/hfsplus/unicode.c === --- linux-2.6.orig/fs/hfsplus/unicode.c 2007-06-25 12:59:15.0 +0200 +++ linux-2.6/fs/hfsplus/unicode.c 2007-06-25 13:35:23.0 +0200 @@ -312,3 +312,126 @@ int hfsplus_asc2uni(struct super_block * return -ENAMETOOLONG; return 0; } + +/* + * Hash a string to an integer as appropriate for the HFS+ filesystem. + * Composed unicode characters are decomposed and case-folding is performed + * if the appropriate bits are (un)set on the superblock. + */ +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) +{ + struct super_block *sb = dentry->d_sb; + const char *astr; + const u16 *dstr; + int casefold, decompose, size, dsize, len; + unsigned long hash; + wchar_t c; + u16 c2; + + casefold = (HFSPLUS_SB(sb).flags & HFSPLUS_SB_CASEFOLD); + decompose = !(HFSPLUS_SB(sb).flags & HFSPLUS_SB_NODECOMPOSE); + hash
Re: [patch 2/2] HFS+: Add custom dentry hash and comparison operations
Hi, On Wed, 20 Jun 2007, Duane Griffin wrote: Add custom dentry hash and comparison operations for HFS+ filesystems that are case-insensitive and/or do automatic unicode decomposition. The new operations reuse the existing HFS+ ASCII to unicode conversion, unicode decomposition and case folding functionality. The changes in the previous patch required a few changes in this patch as well, but there were also a few small problems. The case condition wasn't quite correct and some characters have to be ignored during compare/hash. bye, Roman From: Duane Griffin [EMAIL PROTECTED] Add custom dentry hash and comparison operations for HFS+ filesystems that are case-insensitive and/or do automatic unicode decomposition. The new operations reuse the existing HFS+ ASCII to unicode conversion, unicode decomposition and case folding functionality. Signed-off-by: Duane Griffin [EMAIL PROTECTED] Signed-off-by: Roman Zippel [EMAIL PROTECTED] --- fs/hfsplus/btree.c |4 + fs/hfsplus/dir.c|2 fs/hfsplus/hfsplus_fs.h |4 + fs/hfsplus/inode.c |5 + fs/hfsplus/super.c |1 fs/hfsplus/unicode.c| 123 6 files changed, 138 insertions(+), 1 deletion(-) Index: linux-2.6/fs/hfsplus/dir.c === --- linux-2.6.orig/fs/hfsplus/dir.c 2007-04-26 19:45:57.0 +0200 +++ linux-2.6/fs/hfsplus/dir.c 2007-06-25 13:39:46.0 +0200 @@ -36,6 +36,8 @@ static struct dentry *hfsplus_lookup(str u16 type; sb = dir-i_sb; + + dentry-d_op = hfsplus_dentry_operations; dentry-d_fsdata = NULL; hfs_find_init(HFSPLUS_SB(sb).cat_tree, fd); hfsplus_cat_build_key(sb, fd.search_key, dir-i_ino, dentry-d_name); Index: linux-2.6/fs/hfsplus/hfsplus_fs.h === --- linux-2.6.orig/fs/hfsplus/hfsplus_fs.h 2007-04-26 19:45:57.0 +0200 +++ linux-2.6/fs/hfsplus/hfsplus_fs.h 2007-06-25 12:59:16.0 +0200 @@ -150,6 +150,7 @@ struct hfsplus_sb_info { #define HFSPLUS_SB_NODECOMPOSE 0x0002 #define HFSPLUS_SB_FORCE 0x0004 #define HFSPLUS_SB_HFSX0x0008 +#define HFSPLUS_SB_CASEFOLD0x0010 struct hfsplus_inode_info { @@ -321,6 +322,7 @@ void hfsplus_file_truncate(struct inode /* inode.c */ extern const struct address_space_operations hfsplus_aops; extern const struct address_space_operations hfsplus_btree_aops; +extern struct dentry_operations hfsplus_dentry_operations; void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *); void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *); @@ -353,6 +355,8 @@ int hfsplus_strcasecmp(const struct hfsp int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); +int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2); /* wrapper.c */ int hfsplus_read_wrapper(struct super_block *); Index: linux-2.6/fs/hfsplus/inode.c === --- linux-2.6.orig/fs/hfsplus/inode.c 2007-04-26 19:45:57.0 +0200 +++ linux-2.6/fs/hfsplus/inode.c2007-06-25 13:52:54.0 +0200 @@ -130,6 +130,11 @@ const struct address_space_operations hf .writepages = hfsplus_writepages, }; +struct dentry_operations hfsplus_dentry_operations = { + .d_hash = hfsplus_hash_dentry, + .d_compare= hfsplus_compare_dentry, +}; + static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { Index: linux-2.6/fs/hfsplus/unicode.c === --- linux-2.6.orig/fs/hfsplus/unicode.c 2007-06-25 12:59:15.0 +0200 +++ linux-2.6/fs/hfsplus/unicode.c 2007-06-25 13:35:23.0 +0200 @@ -312,3 +312,126 @@ int hfsplus_asc2uni(struct super_block * return -ENAMETOOLONG; return 0; } + +/* + * Hash a string to an integer as appropriate for the HFS+ filesystem. + * Composed unicode characters are decomposed and case-folding is performed + * if the appropriate bits are (un)set on the superblock. + */ +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) +{ + struct super_block *sb = dentry-d_sb; + const char *astr; + const u16 *dstr; + int casefold, decompose, size, dsize, len; + unsigned long hash; + wchar_t c; + u16 c2; + + casefold = (HFSPLUS_SB(sb).flags HFSPLUS_SB_CASEFOLD); + decompose = !(HFSPLUS_SB(sb).flags HFSPLUS_SB_NODECOMPOSE); + hash =
Re: [patch 2/2] HFS+: Add custom dentry hash and comparison operations
On Mon, 25 Jun 2007 14:17:19 +0200 (CEST) Roman Zippel [EMAIL PROTECTED] wrote: +/* + * Hash a string to an integer as appropriate for the HFS+ filesystem. + * Composed unicode characters are decomposed and case-folding is performed + * if the appropriate bits are (un)set on the superblock. + */ +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) +{ + struct super_block *sb = dentry-d_sb; + const char *astr; + const u16 *dstr; + int casefold, decompose, size, dsize, len; + unsigned long hash; + wchar_t c; + u16 c2; + + casefold = (HFSPLUS_SB(sb).flags HFSPLUS_SB_CASEFOLD); + decompose = !(HFSPLUS_SB(sb).flags HFSPLUS_SB_NODECOMPOSE); + hash = init_name_hash(); + astr = str-name; + len = str-len; + while (len 0) { + size = asc2unichar(sb, astr, len, c); + astr += size; + len -= size; + + if (decompose (dstr = decompose_unichar(c, dsize))) { + do { + c2 = *dstr++; + if (!casefold || (c2 = case_fold(c2))) + hash = partial_name_hash(c2, hash); + } while (--dsize 0); Are you really sure that we cannot start this loop with dsize==0? This isn't obviously true to these bleary eyes. + } else { + c2 = c; + if (!casefold || (c2 = case_fold(c2))) + hash = partial_name_hash(c2, hash); + } + } + str-hash = end_name_hash(hash); - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[patch 2/2] HFS+: Add custom dentry hash and comparison operations
Add custom dentry hash and comparison operations for HFS+ filesystems that are case-insensitive and/or do automatic unicode decomposition. The new operations reuse the existing HFS+ ASCII to unicode conversion, unicode decomposition and case folding functionality. Signed-off-by: Duane Griffin <[EMAIL PROTECTED]> --- --- linux-2.6.21.orig/fs/hfsplus/dir.c +++ linux-2.6.21/fs/hfsplus/dir.c @@ -36,6 +36,11 @@ static struct dentry *hfsplus_lookup(str u16 type; sb = dir->i_sb; + + if (!(HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX) || + !(HFSPLUS_SB(sb).flags & HFSPLUS_SB_NODECOMPOSE)) + dentry->d_op = _dentry_operations; + dentry->d_fsdata = NULL; hfs_find_init(HFSPLUS_SB(sb).cat_tree, ); hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, >d_name); --- linux-2.6.21.orig/fs/hfsplus/hfsplus_fs.h +++ linux-2.6.21/fs/hfsplus/hfsplus_fs.h @@ -321,6 +321,7 @@ void hfsplus_file_truncate(struct inode /* inode.c */ extern const struct address_space_operations hfsplus_aops; extern const struct address_space_operations hfsplus_btree_aops; +extern struct dentry_operations hfsplus_dentry_operations; void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *); void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *); @@ -353,6 +354,8 @@ int hfsplus_strcasecmp(const struct hfsp int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); +int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2); /* wrapper.c */ int hfsplus_read_wrapper(struct super_block *); --- linux-2.6.21.orig/fs/hfsplus/inode.c +++ linux-2.6.21/fs/hfsplus/inode.c @@ -130,6 +130,12 @@ const struct address_space_operations hf .writepages = hfsplus_writepages, }; +struct dentry_operations hfsplus_dentry_operations = { + .d_revalidate = NULL, + .d_hash = hfsplus_hash_dentry, + .d_compare= hfsplus_compare_dentry, +}; + static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { --- linux-2.6.21.orig/fs/hfsplus/super.c +++ linux-2.6.21/fs/hfsplus/super.c @@ -396,6 +396,10 @@ static int hfsplus_fill_super(struct sup } else hfs_find_exit(); + if (!(HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX) || + !(HFSPLUS_SB(sb).flags & HFSPLUS_SB_NODECOMPOSE)) + sb->s_root->d_op = _dentry_operations; + if (sb->s_flags & MS_RDONLY) goto out; --- linux-2.6.21.orig/fs/hfsplus/unicode.c +++ linux-2.6.21/fs/hfsplus/unicode.c @@ -314,6 +314,22 @@ static int asc2ucd(struct super_block *s return size; } +/* + * Convert a ASCII character(s) to a unicode character. + * The unicode character will be decomposed and/or case-folded, if required. + * Returns the number of ASCII characters converted. + */ +static int asc2ucdf(struct super_block *sb, + const char *astr, int len, struct decomposed_uc *duc) +{ + int ii; + int size = asc2ucd(sb, astr, len, duc); + bool fold = !(HFSPLUS_SB(sb).flags & HFSPLUS_SB_HFSX); + for (ii = 0; fold && ii <= duc->size; ++ii) + duc->str[ii] = case_fold(duc->str[ii]); + return size; +} + int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, const char *astr, int len) { @@ -336,3 +352,89 @@ int hfsplus_asc2uni(struct super_block * return -ENAMETOOLONG; return 0; } + +/* + * Hash a string to an integer as appropriate for the HFS+ filesystem. + * Composed unicode characters are decomposed and case-folding is performed + * if the appropriate bits are (un)set on the superblock. + */ +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) +{ + int len = str->len; + const char *astr = str->name; + struct decomposed_uc duc; + unsigned hash = init_name_hash(); + + while (len > 0) { + int ii; + int size = asc2ucdf(dentry->d_sb, astr, len, ); + astr += size; + len -= size; + for (ii = 0; ii < duc.size; ++ii) { + if (duc.str[ii]) + hash = partial_name_hash(duc.str[ii], hash); + } + } + str->hash = end_name_hash(hash); + + return 0; +} + +/* + * Compare strings with HFS+ filename ordering. + * Composed unicode characters are decomposed and case-folding is performed + * if the appropriate bits are (un)set on the superblock. + */ +int +hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) +{ + int off1 = 0; + int off2 = 0;
[patch 2/2] HFS+: Add custom dentry hash and comparison operations
Add custom dentry hash and comparison operations for HFS+ filesystems that are case-insensitive and/or do automatic unicode decomposition. The new operations reuse the existing HFS+ ASCII to unicode conversion, unicode decomposition and case folding functionality. Signed-off-by: Duane Griffin [EMAIL PROTECTED] --- --- linux-2.6.21.orig/fs/hfsplus/dir.c +++ linux-2.6.21/fs/hfsplus/dir.c @@ -36,6 +36,11 @@ static struct dentry *hfsplus_lookup(str u16 type; sb = dir-i_sb; + + if (!(HFSPLUS_SB(sb).flags HFSPLUS_SB_HFSX) || + !(HFSPLUS_SB(sb).flags HFSPLUS_SB_NODECOMPOSE)) + dentry-d_op = hfsplus_dentry_operations; + dentry-d_fsdata = NULL; hfs_find_init(HFSPLUS_SB(sb).cat_tree, fd); hfsplus_cat_build_key(sb, fd.search_key, dir-i_ino, dentry-d_name); --- linux-2.6.21.orig/fs/hfsplus/hfsplus_fs.h +++ linux-2.6.21/fs/hfsplus/hfsplus_fs.h @@ -321,6 +321,7 @@ void hfsplus_file_truncate(struct inode /* inode.c */ extern const struct address_space_operations hfsplus_aops; extern const struct address_space_operations hfsplus_btree_aops; +extern struct dentry_operations hfsplus_dentry_operations; void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *); void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *); @@ -353,6 +354,8 @@ int hfsplus_strcasecmp(const struct hfsp int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); +int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2); /* wrapper.c */ int hfsplus_read_wrapper(struct super_block *); --- linux-2.6.21.orig/fs/hfsplus/inode.c +++ linux-2.6.21/fs/hfsplus/inode.c @@ -130,6 +130,12 @@ const struct address_space_operations hf .writepages = hfsplus_writepages, }; +struct dentry_operations hfsplus_dentry_operations = { + .d_revalidate = NULL, + .d_hash = hfsplus_hash_dentry, + .d_compare= hfsplus_compare_dentry, +}; + static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { --- linux-2.6.21.orig/fs/hfsplus/super.c +++ linux-2.6.21/fs/hfsplus/super.c @@ -396,6 +396,10 @@ static int hfsplus_fill_super(struct sup } else hfs_find_exit(fd); + if (!(HFSPLUS_SB(sb).flags HFSPLUS_SB_HFSX) || + !(HFSPLUS_SB(sb).flags HFSPLUS_SB_NODECOMPOSE)) + sb-s_root-d_op = hfsplus_dentry_operations; + if (sb-s_flags MS_RDONLY) goto out; --- linux-2.6.21.orig/fs/hfsplus/unicode.c +++ linux-2.6.21/fs/hfsplus/unicode.c @@ -314,6 +314,22 @@ static int asc2ucd(struct super_block *s return size; } +/* + * Convert a ASCII character(s) to a unicode character. + * The unicode character will be decomposed and/or case-folded, if required. + * Returns the number of ASCII characters converted. + */ +static int asc2ucdf(struct super_block *sb, + const char *astr, int len, struct decomposed_uc *duc) +{ + int ii; + int size = asc2ucd(sb, astr, len, duc); + bool fold = !(HFSPLUS_SB(sb).flags HFSPLUS_SB_HFSX); + for (ii = 0; fold ii = duc-size; ++ii) + duc-str[ii] = case_fold(duc-str[ii]); + return size; +} + int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, const char *astr, int len) { @@ -336,3 +352,89 @@ int hfsplus_asc2uni(struct super_block * return -ENAMETOOLONG; return 0; } + +/* + * Hash a string to an integer as appropriate for the HFS+ filesystem. + * Composed unicode characters are decomposed and case-folding is performed + * if the appropriate bits are (un)set on the superblock. + */ +int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) +{ + int len = str-len; + const char *astr = str-name; + struct decomposed_uc duc; + unsigned hash = init_name_hash(); + + while (len 0) { + int ii; + int size = asc2ucdf(dentry-d_sb, astr, len, duc); + astr += size; + len -= size; + for (ii = 0; ii duc.size; ++ii) { + if (duc.str[ii]) + hash = partial_name_hash(duc.str[ii], hash); + } + } + str-hash = end_name_hash(hash); + + return 0; +} + +/* + * Compare strings with HFS+ filename ordering. + * Composed unicode characters are decomposed and case-folding is performed + * if the appropriate bits are (un)set on the superblock. + */ +int +hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) +{ + int off1 = 0; + int off2 = 0;