~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/f2fs/hash.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * fs/f2fs/hash.c
  4  *
  5  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  6  *             http://www.samsung.com/
  7  *
  8  * Portions of this code from linux/fs/ext3/hash.c
  9  *
 10  * Copyright (C) 2002 by Theodore Ts'o
 11  */
 12 #include <linux/types.h>
 13 #include <linux/fs.h>
 14 #include <linux/f2fs_fs.h>
 15 #include <linux/pagemap.h>
 16 #include <linux/unicode.h>
 17 
 18 #include "f2fs.h"
 19 
 20 /*
 21  * Hashing code copied from ext3
 22  */
 23 #define DELTA 0x9E3779B9
 24 
 25 static void TEA_transform(unsigned int buf[4], unsigned int const in[])
 26 {
 27         __u32 sum = 0;
 28         __u32 b0 = buf[0], b1 = buf[1];
 29         __u32 a = in[0], b = in[1], c = in[2], d = in[3];
 30         int n = 16;
 31 
 32         do {
 33                 sum += DELTA;
 34                 b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
 35                 b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
 36         } while (--n);
 37 
 38         buf[0] += b0;
 39         buf[1] += b1;
 40 }
 41 
 42 static void str2hashbuf(const unsigned char *msg, size_t len,
 43                                 unsigned int *buf, int num)
 44 {
 45         unsigned pad, val;
 46         int i;
 47 
 48         pad = (__u32)len | ((__u32)len << 8);
 49         pad |= pad << 16;
 50 
 51         val = pad;
 52         if (len > num * 4)
 53                 len = num * 4;
 54         for (i = 0; i < len; i++) {
 55                 if ((i % 4) == 0)
 56                         val = pad;
 57                 val = msg[i] + (val << 8);
 58                 if ((i % 4) == 3) {
 59                         *buf++ = val;
 60                         val = pad;
 61                         num--;
 62                 }
 63         }
 64         if (--num >= 0)
 65                 *buf++ = val;
 66         while (--num >= 0)
 67                 *buf++ = pad;
 68 }
 69 
 70 static u32 TEA_hash_name(const u8 *p, size_t len)
 71 {
 72         __u32 in[8], buf[4];
 73 
 74         /* Initialize the default seed for the hash checksum functions */
 75         buf[0] = 0x67452301;
 76         buf[1] = 0xefcdab89;
 77         buf[2] = 0x98badcfe;
 78         buf[3] = 0x10325476;
 79 
 80         while (1) {
 81                 str2hashbuf(p, len, in, 4);
 82                 TEA_transform(buf, in);
 83                 p += 16;
 84                 if (len <= 16)
 85                         break;
 86                 len -= 16;
 87         }
 88         return buf[0] & ~F2FS_HASH_COL_BIT;
 89 }
 90 
 91 /*
 92  * Compute @fname->hash.  For all directories, @fname->disk_name must be set.
 93  * For casefolded directories, @fname->usr_fname must be set, and also
 94  * @fname->cf_name if the filename is valid Unicode and is not "." or "..".
 95  */
 96 void f2fs_hash_filename(const struct inode *dir, struct f2fs_filename *fname)
 97 {
 98         const u8 *name = fname->disk_name.name;
 99         size_t len = fname->disk_name.len;
100 
101         WARN_ON_ONCE(!name);
102 
103         if (is_dot_dotdot(name, len)) {
104                 fname->hash = 0;
105                 return;
106         }
107 
108 #if IS_ENABLED(CONFIG_UNICODE)
109         if (IS_CASEFOLDED(dir)) {
110                 /*
111                  * If the casefolded name is provided, hash it instead of the
112                  * on-disk name.  If the casefolded name is *not* provided, that
113                  * should only be because the name wasn't valid Unicode or was
114                  * "." or "..", so fall back to treating the name as an opaque
115                  * byte sequence.  Note that to handle encrypted directories,
116                  * the fallback must use usr_fname (plaintext) rather than
117                  * disk_name (ciphertext).
118                  */
119                 WARN_ON_ONCE(!fname->usr_fname->name);
120                 if (fname->cf_name.name) {
121                         name = fname->cf_name.name;
122                         len = fname->cf_name.len;
123                 } else {
124                         name = fname->usr_fname->name;
125                         len = fname->usr_fname->len;
126                 }
127                 if (IS_ENCRYPTED(dir)) {
128                         struct qstr tmp = QSTR_INIT(name, len);
129 
130                         fname->hash =
131                                 cpu_to_le32(fscrypt_fname_siphash(dir, &tmp));
132                         return;
133                 }
134         }
135 #endif
136         fname->hash = cpu_to_le32(TEA_hash_name(name, len));
137 }
138 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php