Despite sharing the same field, only the dentry hash is relevant for the
ordering; the name length must be ignored. This change is necessary in
the module as well.
Xattr length is also irrelevant, so update a comment on that matter.
apfsck/key.c | 12 +++++-------
apfsck/key.h | 2 +-
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/apfsck/key.c b/apfsck/key.c
index a50c176..192564a 100644
--- a/apfsck/key.c
+++ b/apfsck/key.c
@@ -94,7 +94,6 @@ static u32 dentry_hash(const char *name)
struct unicursor cursor;
bool case_fold = apfs_is_case_insensitive();
u32 hash = 0xFFFFFFFF;
- int namelen;
init_unicursor(&cursor, name);
@@ -108,10 +107,8 @@ static u32 dentry_hash(const char *name)
hash = crc32c(hash, &utf32, sizeof(utf32));
}
- /* APFS counts the NULL termination for the filename length */
- namelen = cursor.utf8curr - name;
-
- return ((hash & 0x3FFFFF) << 10) | (namelen & 0x3FF);
+ /* Leave room for the filename length */
+ return (hash & 0x3FFFFF) << 10;
}
/**
@@ -131,13 +128,14 @@ static void read_dir_rec_key(void *raw, int size, struct key *key)
report("Directory record", "filename lacks NULL-termination.");
raw_key = raw;
- key->number = le32_to_cpu(raw_key->name_len_and_hash);
+ /* The filename length is ignored for the ordering, so mask it away */
+ key->number = le32_to_cpu(raw_key->name_len_and_hash) & ~0x3FFU;
key->name = (char *)raw_key->name;
if (key->number != dentry_hash(key->name))
report("Directory record", "filename hash is corrupted.");
- namelen = key->number & 0x3FF;
+ namelen = le32_to_cpu(raw_key->name_len_and_hash) & 0x3FFU;
if (strlen(key->name) + 1 != namelen) {
/* APFS counts the NULL termination for the filename length */
report("Directory record", "wrong name length in key.");
diff --git a/apfsck/key.h b/apfsck/key.h
index f4dac70..6b1516f 100644
--- a/apfsck/key.h
+++ b/apfsck/key.h
@@ -182,7 +182,7 @@ static inline void init_xattr_key(u64 ino, const char *name, struct key *key)
{
key->id = ino;
key->type = APFS_TYPE_XATTR;
- key->number = 0; /* Maybe use the name length here, for speed? */
+ key->number = 0;
key->name = name;
}
--
2.11.0