drm/nouveau/kms/nv50-: use NVIDIA's headers for core head_olut_set()
[linux-2.6-microblaze.git] / fs / f2fs / hash.c
index 8c4ea50..de841aa 100644 (file)
@@ -67,22 +67,9 @@ static void str2hashbuf(const unsigned char *msg, size_t len,
                *buf++ = pad;
 }
 
-static f2fs_hash_t __f2fs_dentry_hash(const struct qstr *name_info,
-                               struct fscrypt_name *fname)
+static u32 TEA_hash_name(const u8 *p, size_t len)
 {
-       __u32 hash;
-       f2fs_hash_t f2fs_hash;
-       const unsigned char *p;
        __u32 in[8], buf[4];
-       const unsigned char *name = name_info->name;
-       size_t len = name_info->len;
-
-       /* encrypted bigname case */
-       if (fname && !fname->disk_name.name)
-               return cpu_to_le32(fname->hash);
-
-       if (is_dot_dotdot(name_info))
-               return 0;
 
        /* Initialize the default seed for the hash checksum functions */
        buf[0] = 0x67452301;
@@ -90,7 +77,6 @@ static f2fs_hash_t __f2fs_dentry_hash(const struct qstr *name_info,
        buf[2] = 0x98badcfe;
        buf[3] = 0x10325476;
 
-       p = name;
        while (1) {
                str2hashbuf(p, len, in, 4);
                TEA_transform(buf, in);
@@ -99,41 +85,43 @@ static f2fs_hash_t __f2fs_dentry_hash(const struct qstr *name_info,
                        break;
                len -= 16;
        }
-       hash = buf[0];
-       f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
-       return f2fs_hash;
+       return buf[0] & ~F2FS_HASH_COL_BIT;
 }
 
-f2fs_hash_t f2fs_dentry_hash(const struct inode *dir,
-               const struct qstr *name_info, struct fscrypt_name *fname)
+/*
+ * Compute @fname->hash.  For all directories, @fname->disk_name must be set.
+ * For casefolded directories, @fname->usr_fname must be set, and also
+ * @fname->cf_name if the filename is valid Unicode.
+ */
+void f2fs_hash_filename(const struct inode *dir, struct f2fs_filename *fname)
 {
-#ifdef CONFIG_UNICODE
-       struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
-       const struct unicode_map *um = sbi->s_encoding;
-       int r, dlen;
-       unsigned char *buff;
-       struct qstr folded;
+       const u8 *name = fname->disk_name.name;
+       size_t len = fname->disk_name.len;
 
-       if (!name_info->len || !IS_CASEFOLDED(dir))
-               goto opaque_seq;
+       WARN_ON_ONCE(!name);
 
-       buff = f2fs_kzalloc(sbi, sizeof(char) * PATH_MAX, GFP_KERNEL);
-       if (!buff)
-               return -ENOMEM;
-
-       dlen = utf8_casefold(um, name_info, buff, PATH_MAX);
-       if (dlen < 0) {
-               kvfree(buff);
-               goto opaque_seq;
+       if (is_dot_dotdot(name, len)) {
+               fname->hash = 0;
+               return;
        }
-       folded.name = buff;
-       folded.len = dlen;
-       r = __f2fs_dentry_hash(&folded, fname);
-
-       kvfree(buff);
-       return r;
 
-opaque_seq:
+#ifdef CONFIG_UNICODE
+       if (IS_CASEFOLDED(dir)) {
+               /*
+                * If the casefolded name is provided, hash it instead of the
+                * on-disk name.  If the casefolded name is *not* provided, that
+                * should only be because the name wasn't valid Unicode, so fall
+                * back to treating the name as an opaque byte sequence.
+                */
+               WARN_ON_ONCE(!fname->usr_fname->name);
+               if (fname->cf_name.name) {
+                       name = fname->cf_name.name;
+                       len = fname->cf_name.len;
+               } else {
+                       name = fname->usr_fname->name;
+                       len = fname->usr_fname->len;
+               }
+       }
 #endif
-       return __f2fs_dentry_hash(name_info, fname);
+       fname->hash = cpu_to_le32(TEA_hash_name(name, len));
 }