summaryrefslogtreecommitdiffstats
path: root/fs/ubifs/dir.c
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2016-11-11 20:46:06 +0100
committerRichard Weinberger <richard@nod.at>2016-12-12 23:07:38 +0100
commit528e3d178f257e36001345d4d61ae5af35422017 (patch)
tree6ad691850c8ab01965cc3b556b746b1828efb002 /fs/ubifs/dir.c
parentubifs: Rename tnc_read_node_nm (diff)
downloadlinux-528e3d178f257e36001345d4d61ae5af35422017.tar.xz
linux-528e3d178f257e36001345d4d61ae5af35422017.zip
ubifs: Add full hash lookup support
UBIFS stores a 32bit hash of every file, for traditional lookups by name this scheme is fine since UBIFS can first try to find the file by the hash of the filename and upon collisions it can walk through all entries with the same hash and do a string compare. When filesnames are encrypted fscrypto will ask the filesystem for a unique cookie, based on this cookie the filesystem has to be able to locate the target file again. With 32bit hashes this is impossible because the chance for collisions is very high. Do deal with that we store a 32bit cookie directly in the UBIFS directory entry node such that we get a 64bit cookie (32bit from filename hash and the dent cookie). For a lookup by hash UBIFS finds the entry by the first 32bit and then compares the dent cookie. If it does not match, it has to do a linear search of the whole directory and compares all dent cookies until the correct entry is found. Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs/dir.c')
-rw-r--r--fs/ubifs/dir.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 7d3bc3fb8831..7f01f3d2ac3b 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -253,7 +253,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
ubifs_assert(fname_len(&nm) == 0);
ubifs_assert(fname_name(&nm) == NULL);
dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
- err = ubifs_tnc_lookup(c, &key, dent);
+ err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
} else {
dent_key_init(c, &key, dir->i_ino, &nm);
err = ubifs_tnc_lookup_nm(c, &key, dent, &nm);
@@ -628,7 +628,10 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
if (encrypted) {
fstr.len = fstr_real_len;
- err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c, &dent->key), 0, &nm.disk_name, &fstr);
+ err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c,
+ &dent->key),
+ le32_to_cpu(dent->cookie),
+ &nm.disk_name, &fstr);
if (err)
goto out;
} else {