123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #include <linux/slab.h>
- #include "internal.h"
- static const char cachefiles_charmap[64] =
- "0123456789"
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "_-"
- ;
- static const char cachefiles_filecharmap[256] = {
-
- [33 ... 46] = 1,
-
- [48 ... 127] = 1,
- };
- char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type)
- {
- unsigned char csum, ch;
- unsigned int acc;
- char *key;
- int loop, len, max, seg, mark, print;
- _enter(",%d", keylen);
- BUG_ON(keylen < 2 || keylen > 514);
- csum = raw[0] + raw[1];
- print = 1;
- for (loop = 2; loop < keylen; loop++) {
- ch = raw[loop];
- csum += ch;
- print &= cachefiles_filecharmap[ch];
- }
- if (print) {
-
- max = keylen - 2;
- max += 2;
- max += 5;
- max += 3 * 2;
- max += 1;
- } else {
-
- keylen = (keylen + 2) / 3;
- max = keylen * 4;
- max += 5;
- max += 3 * 2;
- max += 1;
- }
- max += 1;
- _debug("max: %d", max);
- key = kmalloc(max, cachefiles_gfp);
- if (!key)
- return NULL;
- len = 0;
-
- sprintf(key, "@%02x%c+", (unsigned) csum, 0);
- len = 5;
- mark = len - 1;
- if (print) {
- acc = *(uint16_t *) raw;
- raw += 2;
- key[len + 1] = cachefiles_charmap[acc & 63];
- acc >>= 6;
- key[len] = cachefiles_charmap[acc & 63];
- len += 2;
- seg = 250;
- for (loop = keylen; loop > 0; loop--) {
- if (seg <= 0) {
- key[len++] = '\0';
- mark = len;
- key[len++] = '+';
- seg = 252;
- }
- key[len++] = *raw++;
- ASSERT(len < max);
- }
- switch (type) {
- case FSCACHE_COOKIE_TYPE_INDEX: type = 'I'; break;
- case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'D'; break;
- default: type = 'S'; break;
- }
- } else {
- seg = 252;
- for (loop = keylen; loop > 0; loop--) {
- if (seg <= 0) {
- key[len++] = '\0';
- mark = len;
- key[len++] = '+';
- seg = 252;
- }
- acc = *raw++;
- acc |= *raw++ << 8;
- acc |= *raw++ << 16;
- _debug("acc: %06x", acc);
- key[len++] = cachefiles_charmap[acc & 63];
- acc >>= 6;
- key[len++] = cachefiles_charmap[acc & 63];
- acc >>= 6;
- key[len++] = cachefiles_charmap[acc & 63];
- acc >>= 6;
- key[len++] = cachefiles_charmap[acc & 63];
- ASSERT(len < max);
- }
- switch (type) {
- case FSCACHE_COOKIE_TYPE_INDEX: type = 'J'; break;
- case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'E'; break;
- default: type = 'T'; break;
- }
- }
- key[mark] = type;
- key[len++] = 0;
- key[len] = 0;
- _leave(" = %p %d", key, len);
- return key;
- }
|