lock_parent: don't step on stale ->d_parent of all-but-freed one
[firefly-linux-kernel-4.4.55.git] / fs / f2fs / hash.c
index a60f04200f8badc98e5468367e6cece8354247d1..6eb8d269b53b612b7141b2d101eccfcf840197e0 100644 (file)
@@ -42,7 +42,7 @@ static void TEA_transform(unsigned int buf[4], unsigned int const in[])
        buf[1] += b1;
 }
 
-static void str2hashbuf(const char *msg, int len, unsigned int *buf, int num)
+static void str2hashbuf(const char *msg, size_t len, unsigned int *buf, int num)
 {
        unsigned pad, val;
        int i;
@@ -69,13 +69,17 @@ static void str2hashbuf(const char *msg, int len, unsigned int *buf, int num)
                *buf++ = pad;
 }
 
-f2fs_hash_t f2fs_dentry_hash(const char *name, int len)
+f2fs_hash_t f2fs_dentry_hash(const char *name, size_t len)
 {
-       __u32 hash, minor_hash;
+       __u32 hash;
        f2fs_hash_t f2fs_hash;
        const char *p;
        __u32 in[8], buf[4];
 
+       if ((len <= 2) && (name[0] == '.') &&
+               (name[1] == '.' || name[1] == '\0'))
+               return 0;
+
        /* Initialize the default seed for the hash checksum functions */
        buf[0] = 0x67452301;
        buf[1] = 0xefcdab89;
@@ -83,15 +87,15 @@ f2fs_hash_t f2fs_dentry_hash(const char *name, int len)
        buf[3] = 0x10325476;
 
        p = name;
-       while (len > 0) {
+       while (1) {
                str2hashbuf(p, len, in, 4);
                TEA_transform(buf, in);
-               len -= 16;
                p += 16;
+               if (len <= 16)
+                       break;
+               len -= 16;
        }
        hash = buf[0];
-       minor_hash = buf[1];
-
        f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
        return f2fs_hash;
 }