Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / include / obd_cksum.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #ifndef __OBD_CKSUM
38 #define __OBD_CKSUM
39
40 #if defined(__linux__)
41 #include <linux/obd_cksum.h>
42 #elif defined(__APPLE__)
43 #include <darwin/obd_chksum.h>
44 #elif defined(__WINNT__)
45 #include <winnt/obd_cksum.h>
46 #else
47 #error Unsupported operating system.
48 #endif
49
50 #include <lustre/lustre_idl.h>
51
52 /*
53  * Checksums
54  */
55
56 #ifndef HAVE_ARCH_CRC32
57 /* crc32_le lifted from the Linux kernel, which had the following to say:
58  *
59  * This code is in the public domain; copyright abandoned.
60  * Liability for non-performance of this code is limited to the amount
61  * you paid for it.  Since it is distributed for free, your refund will
62  * be very very small.  If it breaks, you get to keep both pieces.
63  */
64 #define CRCPOLY_LE 0xedb88320
65 /**
66  * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
67  * @crc - seed value for computation.  ~0 for Ethernet, sometimes 0 for
68  *        other uses, or the previous crc32 value if computing incrementally.
69  * @p   - pointer to buffer over which CRC is run
70  * @len - length of buffer @p
71  */
72 static inline __u32 crc32_le(__u32 crc, unsigned char const *p, size_t len)
73 {
74         int i;
75         while (len--) {
76                 crc ^= *p++;
77                 for (i = 0; i < 8; i++)
78                         crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
79         }
80         return crc;
81 }
82 #endif
83
84 static inline __u32 init_checksum(cksum_type_t cksum_type)
85 {
86         switch(cksum_type) {
87         case OBD_CKSUM_CRC32:
88                 return ~0U;
89 #ifdef HAVE_ADLER
90         case OBD_CKSUM_ADLER:
91                 return 1U;
92 #endif
93         default:
94                 CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
95                 LBUG();
96         }
97         return 0;
98 }
99
100 static inline __u32 compute_checksum(__u32 cksum, unsigned char const *p,
101                                      size_t len, cksum_type_t cksum_type)
102 {
103         switch(cksum_type) {
104         case OBD_CKSUM_CRC32:
105                 return crc32_le(cksum, p, len);
106 #ifdef HAVE_ADLER
107         case OBD_CKSUM_ADLER:
108                 return adler32(cksum, p, len);
109 #endif
110         default:
111                 CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
112                 LBUG();
113         }
114         return 0;
115 }
116
117 static inline obd_flag cksum_type_pack(cksum_type_t cksum_type)
118 {
119         switch(cksum_type) {
120         case OBD_CKSUM_CRC32:
121                 return OBD_FL_CKSUM_CRC32;
122 #ifdef HAVE_ADLER
123         case OBD_CKSUM_ADLER:
124                 return OBD_FL_CKSUM_ADLER;
125 #endif
126         default:
127                 CWARN("unknown cksum type %x\n", cksum_type);
128         }
129         return OBD_FL_CKSUM_CRC32;
130 }
131
132 static inline cksum_type_t cksum_type_unpack(obd_flag o_flags)
133 {
134         o_flags &= OBD_FL_CKSUM_ALL;
135         if ((o_flags - 1) & o_flags)
136                 CWARN("several checksum types are set: %x\n", o_flags);
137         if (o_flags & OBD_FL_CKSUM_ADLER)
138 #ifdef HAVE_ADLER
139                 return OBD_CKSUM_ADLER;
140 #else
141                 CWARN("checksum type is set to adler32, but adler32 is not "
142                       "supported (%x)\n", o_flags);
143 #endif
144         return OBD_CKSUM_CRC32;
145 }
146
147 #ifdef HAVE_ADLER
148 /* Default preferred checksum algorithm to use (if supported by the server) */
149 #define OSC_DEFAULT_CKSUM OBD_CKSUM_ADLER
150 /* Adler-32 is supported */
151 #define CHECKSUM_ADLER OBD_CKSUM_ADLER
152 #else
153 #define OSC_DEFAULT_CKSUM OBD_CKSUM_CRC32
154 #define CHECKSUM_ADLER 0
155 #endif
156
157 #define OBD_CKSUM_ALL (OBD_CKSUM_CRC32 | CHECKSUM_ADLER)
158
159 /* Checksum algorithm names. Must be defined in the same order as the
160  * OBD_CKSUM_* flags. */
161 #define DECLARE_CKSUM_NAME char *cksum_name[] = {"crc32", "adler"}
162
163 #endif /* __OBD_H */