Whamcloud - gitweb
LU-4573 tests: check all MDTs for open files
[fs/lustre-release.git] / libcfs / libcfs / posix / posix-crc32.c
1 /*
2  *      This file contains part of linux kernel implementation of crc32
3  *      kernel version 2.6.32
4  */
5 #include <endian.h>
6 #include <libcfs/libcfs.h>
7 #define CRCPOLY_LE      0xedb88320
8 #define CRC_LE_BITS     8
9 #define LE_TABLE_SIZE   (1 << CRC_LE_BITS)
10
11 static unsigned int crc32table_le[LE_TABLE_SIZE];
12 /**
13  * crc32init_le() - allocate and initialize LE table data
14  *
15  * crc is the crc of the byte i; other entries are filled in based on the
16  * fact that crctable[i^j] = crctable[i] ^ crctable[j].
17  *
18  */
19 void crc32init_le(void)
20 {
21         unsigned i, j;
22         unsigned int crc = 1;
23
24         crc32table_le[0] = 0;
25
26         for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
27                 crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
28                 for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
29                         crc32table_le[i + j] = crc ^ crc32table_le[j];
30         }
31 }
32
33 unsigned int crc32_le(unsigned int crc, unsigned char const *p, size_t len)
34 {
35         const unsigned int      *b = (unsigned int *)p;
36         const unsigned int      *tab = crc32table_le;
37
38 # if __BYTE_ORDER == __LITTLE_ENDIAN
39 #  define DO_CRC(x) crc = tab[(crc ^ (x)) & 255] ^ (crc>>8)
40 # else
41 #  define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc<<8)
42 # endif
43
44         crc = cpu_to_le32(crc);
45         /* Align it */
46         if (unlikely(((long)b) & 3 && len)) {
47                 do {
48                         unsigned char *p = (unsigned char *)b;
49                         DO_CRC(*p++);
50                         b = (void *)p;
51                 } while ((--len) && ((long)b) & 3);
52         }
53         if (likely(len >= 4)) {
54                 /* load data 32 bits wide, xor data 32 bits wide. */
55                 size_t save_len = len & 3;
56                 len = len >> 2;
57                 --b; /* use pre increment below(*++b) for speed */
58                 do {
59                         crc ^= *++b;
60                         DO_CRC(0);
61                         DO_CRC(0);
62                         DO_CRC(0);
63                         DO_CRC(0);
64                 } while (--len);
65                 b++; /* point to next byte(s) */
66                 len = save_len;
67         }
68         /* And the last few bytes */
69         if (len) {
70                 do {
71                         unsigned char *p = (unsigned char *)b;
72                         DO_CRC(*p++);
73                         b = (void *)p;
74                 } while (--len);
75         }
76
77         return le32_to_cpu(crc);
78 #undef DO_CRC
79 }