diff options
author | Kent Overstreet <koverstreet@google.com> | 2013-03-23 19:11:31 -0400 |
---|---|---|
committer | Kent Overstreet <koverstreet@google.com> | 2013-03-23 19:11:31 -0400 |
commit | cafe563591446cf80bfbc2fe3bc72a2e36cf1060 (patch) | |
tree | c8ae27b13dcdb0219634376ca5e667df32b1173a /drivers/md/bcache/util.h | |
parent | ea6749c705d9e629ed03c7336cc929fc6014b834 (diff) |
bcache: A block layer cache
Does writethrough and writeback caching, handles unclean shutdown, and
has a bunch of other nifty features motivated by real world usage.
See the wiki at http://bcache.evilpiepirate.org for more.
Signed-off-by: Kent Overstreet <koverstreet@google.com>
Diffstat (limited to 'drivers/md/bcache/util.h')
-rw-r--r-- | drivers/md/bcache/util.h | 589 |
1 files changed, 589 insertions, 0 deletions
diff --git a/drivers/md/bcache/util.h b/drivers/md/bcache/util.h new file mode 100644 index 000000000000..56705fdcc149 --- /dev/null +++ b/drivers/md/bcache/util.h | |||
@@ -0,0 +1,589 @@ | |||
1 | |||
2 | #ifndef _BCACHE_UTIL_H | ||
3 | #define _BCACHE_UTIL_H | ||
4 | |||
5 | #include <linux/errno.h> | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/llist.h> | ||
8 | #include <linux/ratelimit.h> | ||
9 | #include <linux/vmalloc.h> | ||
10 | #include <linux/workqueue.h> | ||
11 | |||
12 | #include "closure.h" | ||
13 | |||
14 | #define PAGE_SECTORS (PAGE_SIZE / 512) | ||
15 | |||
16 | struct closure; | ||
17 | |||
18 | #include <trace/events/bcache.h> | ||
19 | |||
20 | #ifdef CONFIG_BCACHE_EDEBUG | ||
21 | |||
22 | #define atomic_dec_bug(v) BUG_ON(atomic_dec_return(v) < 0) | ||
23 | #define atomic_inc_bug(v, i) BUG_ON(atomic_inc_return(v) <= i) | ||
24 | |||
25 | #else /* EDEBUG */ | ||
26 | |||
27 | #define atomic_dec_bug(v) atomic_dec(v) | ||
28 | #define atomic_inc_bug(v, i) atomic_inc(v) | ||
29 | |||
30 | #endif | ||
31 | |||
32 | #define BITMASK(name, type, field, offset, size) \ | ||
33 | static inline uint64_t name(const type *k) \ | ||
34 | { return (k->field >> offset) & ~(((uint64_t) ~0) << size); } \ | ||
35 | \ | ||
36 | static inline void SET_##name(type *k, uint64_t v) \ | ||
37 | { \ | ||
38 | k->field &= ~(~((uint64_t) ~0 << size) << offset); \ | ||
39 | k->field |= v << offset; \ | ||
40 | } | ||
41 | |||
42 | #define DECLARE_HEAP(type, name) \ | ||
43 | struct { \ | ||
44 | size_t size, used; \ | ||
45 | type *data; \ | ||
46 | } name | ||
47 | |||
48 | #define init_heap(heap, _size, gfp) \ | ||
49 | ({ \ | ||
50 | size_t _bytes; \ | ||
51 | (heap)->used = 0; \ | ||
52 | (heap)->size = (_size); \ | ||
53 | _bytes = (heap)->size * sizeof(*(heap)->data); \ | ||
54 | (heap)->data = NULL; \ | ||
55 | if (_bytes < KMALLOC_MAX_SIZE) \ | ||
56 | (heap)->data = kmalloc(_bytes, (gfp)); \ | ||
57 | if ((!(heap)->data) && ((gfp) & GFP_KERNEL)) \ | ||
58 | (heap)->data = vmalloc(_bytes); \ | ||
59 | (heap)->data; \ | ||
60 | }) | ||
61 | |||
62 | #define free_heap(heap) \ | ||
63 | do { \ | ||
64 | if (is_vmalloc_addr((heap)->data)) \ | ||
65 | vfree((heap)->data); \ | ||
66 | else \ | ||
67 | kfree((heap)->data); \ | ||
68 | (heap)->data = NULL; \ | ||
69 | } while (0) | ||
70 | |||
71 | #define heap_swap(h, i, j) swap((h)->data[i], (h)->data[j]) | ||
72 | |||
73 | #define heap_sift(h, i, cmp) \ | ||
74 | do { \ | ||
75 | size_t _r, _j = i; \ | ||
76 | \ | ||
77 | for (; _j * 2 + 1 < (h)->used; _j = _r) { \ | ||
78 | _r = _j * 2 + 1; \ | ||
79 | if (_r + 1 < (h)->used && \ | ||
80 | cmp((h)->data[_r], (h)->data[_r + 1])) \ | ||
81 | _r++; \ | ||
82 | \ | ||
83 | if (cmp((h)->data[_r], (h)->data[_j])) \ | ||
84 | break; \ | ||
85 | heap_swap(h, _r, _j); \ | ||
86 | } \ | ||
87 | } while (0) | ||
88 | |||
89 | #define heap_sift_down(h, i, cmp) \ | ||
90 | do { \ | ||
91 | while (i) { \ | ||
92 | size_t p = (i - 1) / 2; \ | ||
93 | if (cmp((h)->data[i], (h)->data[p])) \ | ||
94 | break; \ | ||
95 | heap_swap(h, i, p); \ | ||
96 | i = p; \ | ||
97 | } \ | ||
98 | } while (0) | ||
99 | |||
100 | #define heap_add(h, d, cmp) \ | ||
101 | ({ \ | ||
102 | bool _r = !heap_full(h); \ | ||
103 | if (_r) { \ | ||
104 | size_t _i = (h)->used++; \ | ||
105 | (h)->data[_i] = d; \ | ||
106 | \ | ||
107 | heap_sift_down(h, _i, cmp); \ | ||
108 | heap_sift(h, _i, cmp); \ | ||
109 | } \ | ||
110 | _r; \ | ||
111 | }) | ||
112 | |||
113 | #define heap_pop(h, d, cmp) \ | ||
114 | ({ \ | ||
115 | bool _r = (h)->used; \ | ||
116 | if (_r) { \ | ||
117 | (d) = (h)->data[0]; \ | ||
118 | (h)->used--; \ | ||
119 | heap_swap(h, 0, (h)->used); \ | ||
120 | heap_sift(h, 0, cmp); \ | ||
121 | } \ | ||
122 | _r; \ | ||
123 | }) | ||
124 | |||
125 | #define heap_peek(h) ((h)->size ? (h)->data[0] : NULL) | ||
126 | |||
127 | #define heap_full(h) ((h)->used == (h)->size) | ||
128 | |||
129 | #define DECLARE_FIFO(type, name) \ | ||
130 | struct { \ | ||
131 | size_t front, back, size, mask; \ | ||
132 | type *data; \ | ||
133 | } name | ||
134 | |||
135 | #define fifo_for_each(c, fifo, iter) \ | ||
136 | for (iter = (fifo)->front; \ | ||
137 | c = (fifo)->data[iter], iter != (fifo)->back; \ | ||
138 | iter = (iter + 1) & (fifo)->mask) | ||
139 | |||
140 | #define __init_fifo(fifo, gfp) \ | ||
141 | ({ \ | ||
142 | size_t _allocated_size, _bytes; \ | ||
143 | BUG_ON(!(fifo)->size); \ | ||
144 | \ | ||
145 | _allocated_size = roundup_pow_of_two((fifo)->size + 1); \ | ||
146 | _bytes = _allocated_size * sizeof(*(fifo)->data); \ | ||
147 | \ | ||
148 | (fifo)->mask = _allocated_size - 1; \ | ||
149 | (fifo)->front = (fifo)->back = 0; \ | ||
150 | (fifo)->data = NULL; \ | ||
151 | \ | ||
152 | if (_bytes < KMALLOC_MAX_SIZE) \ | ||
153 | (fifo)->data = kmalloc(_bytes, (gfp)); \ | ||
154 | if ((!(fifo)->data) && ((gfp) & GFP_KERNEL)) \ | ||
155 | (fifo)->data = vmalloc(_bytes); \ | ||
156 | (fifo)->data; \ | ||
157 | }) | ||
158 | |||
159 | #define init_fifo_exact(fifo, _size, gfp) \ | ||
160 | ({ \ | ||
161 | (fifo)->size = (_size); \ | ||
162 | __init_fifo(fifo, gfp); \ | ||
163 | }) | ||
164 | |||
165 | #define init_fifo(fifo, _size, gfp) \ | ||
166 | ({ \ | ||
167 | (fifo)->size = (_size); \ | ||
168 | if ((fifo)->size > 4) \ | ||
169 | (fifo)->size = roundup_pow_of_two((fifo)->size) - 1; \ | ||
170 | __init_fifo(fifo, gfp); \ | ||
171 | }) | ||
172 | |||
173 | #define free_fifo(fifo) \ | ||
174 | do { \ | ||
175 | if (is_vmalloc_addr((fifo)->data)) \ | ||
176 | vfree((fifo)->data); \ | ||
177 | else \ | ||
178 | kfree((fifo)->data); \ | ||
179 | (fifo)->data = NULL; \ | ||
180 | } while (0) | ||
181 | |||
182 | #define fifo_used(fifo) (((fifo)->back - (fifo)->front) & (fifo)->mask) | ||
183 | #define fifo_free(fifo) ((fifo)->size - fifo_used(fifo)) | ||
184 | |||
185 | #define fifo_empty(fifo) (!fifo_used(fifo)) | ||
186 | #define fifo_full(fifo) (!fifo_free(fifo)) | ||
187 | |||
188 | #define fifo_front(fifo) ((fifo)->data[(fifo)->front]) | ||
189 | #define fifo_back(fifo) \ | ||
190 | ((fifo)->data[((fifo)->back - 1) & (fifo)->mask]) | ||
191 | |||
192 | #define fifo_idx(fifo, p) (((p) - &fifo_front(fifo)) & (fifo)->mask) | ||
193 | |||
194 | #define fifo_push_back(fifo, i) \ | ||
195 | ({ \ | ||
196 | bool _r = !fifo_full((fifo)); \ | ||
197 | if (_r) { \ | ||
198 | (fifo)->data[(fifo)->back++] = (i); \ | ||
199 | (fifo)->back &= (fifo)->mask; \ | ||
200 | } \ | ||
201 | _r; \ | ||
202 | }) | ||
203 | |||
204 | #define fifo_pop_front(fifo, i) \ | ||
205 | ({ \ | ||
206 | bool _r = !fifo_empty((fifo)); \ | ||
207 | if (_r) { \ | ||
208 | (i) = (fifo)->data[(fifo)->front++]; \ | ||
209 | (fifo)->front &= (fifo)->mask; \ | ||
210 | } \ | ||
211 | _r; \ | ||
212 | }) | ||
213 | |||
214 | #define fifo_push_front(fifo, i) \ | ||
215 | ({ \ | ||
216 | bool _r = !fifo_full((fifo)); \ | ||
217 | if (_r) { \ | ||
218 | --(fifo)->front; \ | ||
219 | (fifo)->front &= (fifo)->mask; \ | ||
220 | (fifo)->data[(fifo)->front] = (i); \ | ||
221 | } \ | ||
222 | _r; \ | ||
223 | }) | ||
224 | |||
225 | #define fifo_pop_back(fifo, i) \ | ||
226 | ({ \ | ||
227 | bool _r = !fifo_empty((fifo)); \ | ||
228 | if (_r) { \ | ||
229 | --(fifo)->back; \ | ||
230 | (fifo)->back &= (fifo)->mask; \ | ||
231 | (i) = (fifo)->data[(fifo)->back] \ | ||
232 | } \ | ||
233 | _r; \ | ||
234 | }) | ||
235 | |||
236 | #define fifo_push(fifo, i) fifo_push_back(fifo, (i)) | ||
237 | #define fifo_pop(fifo, i) fifo_pop_front(fifo, (i)) | ||
238 | |||
239 | #define fifo_swap(l, r) \ | ||
240 | do { \ | ||
241 | swap((l)->front, (r)->front); \ | ||
242 | swap((l)->back, (r)->back); \ | ||
243 | swap((l)->size, (r)->size); \ | ||
244 | swap((l)->mask, (r)->mask); \ | ||
245 | swap((l)->data, (r)->data); \ | ||
246 | } while (0) | ||
247 | |||
248 | #define fifo_move(dest, src) \ | ||
249 | do { \ | ||
250 | typeof(*((dest)->data)) _t; \ | ||
251 | while (!fifo_full(dest) && \ | ||
252 | fifo_pop(src, _t)) \ | ||
253 | fifo_push(dest, _t); \ | ||
254 | } while (0) | ||
255 | |||
256 | /* | ||
257 | * Simple array based allocator - preallocates a number of elements and you can | ||
258 | * never allocate more than that, also has no locking. | ||
259 | * | ||
260 | * Handy because if you know you only need a fixed number of elements you don't | ||
261 | * have to worry about memory allocation failure, and sometimes a mempool isn't | ||
262 | * what you want. | ||
263 | * | ||
264 | * We treat the free elements as entries in a singly linked list, and the | ||
265 | * freelist as a stack - allocating and freeing push and pop off the freelist. | ||
266 | */ | ||
267 | |||
268 | #define DECLARE_ARRAY_ALLOCATOR(type, name, size) \ | ||
269 | struct { \ | ||
270 | type *freelist; \ | ||
271 | type data[size]; \ | ||
272 | } name | ||
273 | |||
274 | #define array_alloc(array) \ | ||
275 | ({ \ | ||
276 | typeof((array)->freelist) _ret = (array)->freelist; \ | ||
277 | \ | ||
278 | if (_ret) \ | ||
279 | (array)->freelist = *((typeof((array)->freelist) *) _ret);\ | ||
280 | \ | ||
281 | _ret; \ | ||
282 | }) | ||
283 | |||
284 | #define array_free(array, ptr) \ | ||
285 | do { \ | ||
286 | typeof((array)->freelist) _ptr = ptr; \ | ||
287 | \ | ||
288 | *((typeof((array)->freelist) *) _ptr) = (array)->freelist; \ | ||
289 | (array)->freelist = _ptr; \ | ||
290 | } while (0) | ||
291 | |||
292 | #define array_allocator_init(array) \ | ||
293 | do { \ | ||
294 | typeof((array)->freelist) _i; \ | ||
295 | \ | ||
296 | BUILD_BUG_ON(sizeof((array)->data[0]) < sizeof(void *)); \ | ||
297 | (array)->freelist = NULL; \ | ||
298 | \ | ||
299 | for (_i = (array)->data; \ | ||
300 | _i < (array)->data + ARRAY_SIZE((array)->data); \ | ||
301 | _i++) \ | ||
302 | array_free(array, _i); \ | ||
303 | } while (0) | ||
304 | |||
305 | #define array_freelist_empty(array) ((array)->freelist == NULL) | ||
306 | |||
307 | #define ANYSINT_MAX(t) \ | ||
308 | ((((t) 1 << (sizeof(t) * 8 - 2)) - (t) 1) * (t) 2 + (t) 1) | ||
309 | |||
310 | int strtoint_h(const char *, int *); | ||
311 | int strtouint_h(const char *, unsigned int *); | ||
312 | int strtoll_h(const char *, long long *); | ||
313 | int strtoull_h(const char *, unsigned long long *); | ||
314 | |||
315 | static inline int strtol_h(const char *cp, long *res) | ||
316 | { | ||
317 | #if BITS_PER_LONG == 32 | ||
318 | return strtoint_h(cp, (int *) res); | ||
319 | #else | ||
320 | return strtoll_h(cp, (long long *) res); | ||
321 | #endif | ||
322 | } | ||
323 | |||
324 | static inline int strtoul_h(const char *cp, long *res) | ||
325 | { | ||
326 | #if BITS_PER_LONG == 32 | ||
327 | return strtouint_h(cp, (unsigned int *) res); | ||
328 | #else | ||
329 | return strtoull_h(cp, (unsigned long long *) res); | ||
330 | #endif | ||
331 | } | ||
332 | |||
333 | #define strtoi_h(cp, res) \ | ||
334 | (__builtin_types_compatible_p(typeof(*res), int) \ | ||
335 | ? strtoint_h(cp, (void *) res) \ | ||
336 | : __builtin_types_compatible_p(typeof(*res), long) \ | ||
337 | ? strtol_h(cp, (void *) res) \ | ||
338 | : __builtin_types_compatible_p(typeof(*res), long long) \ | ||
339 | ? strtoll_h(cp, (void *) res) \ | ||
340 | : __builtin_types_compatible_p(typeof(*res), unsigned int) \ | ||
341 | ? strtouint_h(cp, (void *) res) \ | ||
342 | : __builtin_types_compatible_p(typeof(*res), unsigned long) \ | ||
343 | ? strtoul_h(cp, (void *) res) \ | ||
344 | : __builtin_types_compatible_p(typeof(*res), unsigned long long)\ | ||
345 | ? strtoull_h(cp, (void *) res) : -EINVAL) | ||
346 | |||
347 | #define strtoul_safe(cp, var) \ | ||
348 | ({ \ | ||
349 | unsigned long _v; \ | ||
350 | int _r = kstrtoul(cp, 10, &_v); \ | ||
351 | if (!_r) \ | ||
352 | var = _v; \ | ||
353 | _r; \ | ||
354 | }) | ||
355 | |||
356 | #define strtoul_safe_clamp(cp, var, min, max) \ | ||
357 | ({ \ | ||
358 | unsigned long _v; \ | ||
359 | int _r = kstrtoul(cp, 10, &_v); \ | ||
360 | if (!_r) \ | ||
361 | var = clamp_t(typeof(var), _v, min, max); \ | ||
362 | _r; \ | ||
363 | }) | ||
364 | |||
365 | #define snprint(buf, size, var) \ | ||
366 | snprintf(buf, size, \ | ||
367 | __builtin_types_compatible_p(typeof(var), int) \ | ||
368 | ? "%i\n" : \ | ||
369 | __builtin_types_compatible_p(typeof(var), unsigned) \ | ||
370 | ? "%u\n" : \ | ||
371 | __builtin_types_compatible_p(typeof(var), long) \ | ||
372 | ? "%li\n" : \ | ||
373 | __builtin_types_compatible_p(typeof(var), unsigned long)\ | ||
374 | ? "%lu\n" : \ | ||
375 | __builtin_types_compatible_p(typeof(var), int64_t) \ | ||
376 | ? "%lli\n" : \ | ||
377 | __builtin_types_compatible_p(typeof(var), uint64_t) \ | ||
378 | ? "%llu\n" : \ | ||
379 | __builtin_types_compatible_p(typeof(var), const char *) \ | ||
380 | ? "%s\n" : "%i\n", var) | ||
381 | |||
382 | ssize_t hprint(char *buf, int64_t v); | ||
383 | |||
384 | bool is_zero(const char *p, size_t n); | ||
385 | int parse_uuid(const char *s, char *uuid); | ||
386 | |||
387 | ssize_t snprint_string_list(char *buf, size_t size, const char * const list[], | ||
388 | size_t selected); | ||
389 | |||
390 | ssize_t read_string_list(const char *buf, const char * const list[]); | ||
391 | |||
392 | struct time_stats { | ||
393 | /* | ||
394 | * all fields are in nanoseconds, averages are ewmas stored left shifted | ||
395 | * by 8 | ||
396 | */ | ||
397 | uint64_t max_duration; | ||
398 | uint64_t average_duration; | ||
399 | uint64_t average_frequency; | ||
400 | uint64_t last; | ||
401 | }; | ||
402 | |||
403 | void time_stats_update(struct time_stats *stats, uint64_t time); | ||
404 | |||
405 | #define NSEC_PER_ns 1L | ||
406 | #define NSEC_PER_us NSEC_PER_USEC | ||
407 | #define NSEC_PER_ms NSEC_PER_MSEC | ||
408 | #define NSEC_PER_sec NSEC_PER_SEC | ||
409 | |||
410 | #define __print_time_stat(stats, name, stat, units) \ | ||
411 | sysfs_print(name ## _ ## stat ## _ ## units, \ | ||
412 | div_u64((stats)->stat >> 8, NSEC_PER_ ## units)) | ||
413 | |||
414 | #define sysfs_print_time_stats(stats, name, \ | ||
415 | frequency_units, \ | ||
416 | duration_units) \ | ||
417 | do { \ | ||
418 | __print_time_stat(stats, name, \ | ||
419 | average_frequency, frequency_units); \ | ||
420 | __print_time_stat(stats, name, \ | ||
421 | average_duration, duration_units); \ | ||
422 | __print_time_stat(stats, name, \ | ||
423 | max_duration, duration_units); \ | ||
424 | \ | ||
425 | sysfs_print(name ## _last_ ## frequency_units, (stats)->last \ | ||
426 | ? div_s64(local_clock() - (stats)->last, \ | ||
427 | NSEC_PER_ ## frequency_units) \ | ||
428 | : -1LL); \ | ||
429 | } while (0) | ||
430 | |||
431 | #define sysfs_time_stats_attribute(name, \ | ||
432 | frequency_units, \ | ||
433 | duration_units) \ | ||
434 | read_attribute(name ## _average_frequency_ ## frequency_units); \ | ||
435 | read_attribute(name ## _average_duration_ ## duration_units); \ | ||
436 | read_attribute(name ## _max_duration_ ## duration_units); \ | ||
437 | read_attribute(name ## _last_ ## frequency_units) | ||
438 | |||
439 | #define sysfs_time_stats_attribute_list(name, \ | ||
440 | frequency_units, \ | ||
441 | duration_units) \ | ||
442 | &sysfs_ ## name ## _average_frequency_ ## frequency_units, \ | ||
443 | &sysfs_ ## name ## _average_duration_ ## duration_units, \ | ||
444 | &sysfs_ ## name ## _max_duration_ ## duration_units, \ | ||
445 | &sysfs_ ## name ## _last_ ## frequency_units, | ||
446 | |||
447 | #define ewma_add(ewma, val, weight, factor) \ | ||
448 | ({ \ | ||
449 | (ewma) *= (weight) - 1; \ | ||
450 | (ewma) += (val) << factor; \ | ||
451 | (ewma) /= (weight); \ | ||
452 | (ewma) >> factor; \ | ||
453 | }) | ||
454 | |||
455 | struct ratelimit { | ||
456 | uint64_t next; | ||
457 | unsigned rate; | ||
458 | }; | ||
459 | |||
460 | static inline void ratelimit_reset(struct ratelimit *d) | ||
461 | { | ||
462 | d->next = local_clock(); | ||
463 | } | ||
464 | |||
465 | unsigned next_delay(struct ratelimit *d, uint64_t done); | ||
466 | |||
467 | #define __DIV_SAFE(n, d, zero) \ | ||
468 | ({ \ | ||
469 | typeof(n) _n = (n); \ | ||
470 | typeof(d) _d = (d); \ | ||
471 | _d ? _n / _d : zero; \ | ||
472 | }) | ||
473 | |||
474 | #define DIV_SAFE(n, d) __DIV_SAFE(n, d, 0) | ||
475 | |||
476 | #define container_of_or_null(ptr, type, member) \ | ||
477 | ({ \ | ||
478 | typeof(ptr) _ptr = ptr; \ | ||
479 | _ptr ? container_of(_ptr, type, member) : NULL; \ | ||
480 | }) | ||
481 | |||
482 | #define RB_INSERT(root, new, member, cmp) \ | ||
483 | ({ \ | ||
484 | __label__ dup; \ | ||
485 | struct rb_node **n = &(root)->rb_node, *parent = NULL; \ | ||
486 | typeof(new) this; \ | ||
487 | int res, ret = -1; \ | ||
488 | \ | ||
489 | while (*n) { \ | ||
490 | parent = *n; \ | ||
491 | this = container_of(*n, typeof(*(new)), member); \ | ||
492 | res = cmp(new, this); \ | ||
493 | if (!res) \ | ||
494 | goto dup; \ | ||
495 | n = res < 0 \ | ||
496 | ? &(*n)->rb_left \ | ||
497 | : &(*n)->rb_right; \ | ||
498 | } \ | ||
499 | \ | ||
500 | rb_link_node(&(new)->member, parent, n); \ | ||
501 | rb_insert_color(&(new)->member, root); \ | ||
502 | ret = 0; \ | ||
503 | dup: \ | ||
504 | ret; \ | ||
505 | }) | ||
506 | |||
507 | #define RB_SEARCH(root, search, member, cmp) \ | ||
508 | ({ \ | ||
509 | struct rb_node *n = (root)->rb_node; \ | ||
510 | typeof(&(search)) this, ret = NULL; \ | ||
511 | int res; \ | ||
512 | \ | ||
513 | while (n) { \ | ||
514 | this = container_of(n, typeof(search), member); \ | ||
515 | res = cmp(&(search), this); \ | ||
516 | if (!res) { \ | ||
517 | ret = this; \ | ||
518 | break; \ | ||
519 | } \ | ||
520 | n = res < 0 \ | ||
521 | ? n->rb_left \ | ||
522 | : n->rb_right; \ | ||
523 | } \ | ||
524 | ret; \ | ||
525 | }) | ||
526 | |||
527 | #define RB_GREATER(root, search, member, cmp) \ | ||
528 | ({ \ | ||
529 | struct rb_node *n = (root)->rb_node; \ | ||
530 | typeof(&(search)) this, ret = NULL; \ | ||
531 | int res; \ | ||
532 | \ | ||
533 | while (n) { \ | ||
534 | this = container_of(n, typeof(search), member); \ | ||
535 | res = cmp(&(search), this); \ | ||
536 | if (res < 0) { \ | ||
537 | ret = this; \ | ||
538 | n = n->rb_left; \ | ||
539 | } else \ | ||
540 | n = n->rb_right; \ | ||
541 | } \ | ||
542 | ret; \ | ||
543 | }) | ||
544 | |||
545 | #define RB_FIRST(root, type, member) \ | ||
546 | container_of_or_null(rb_first(root), type, member) | ||
547 | |||
548 | #define RB_LAST(root, type, member) \ | ||
549 | container_of_or_null(rb_last(root), type, member) | ||
550 | |||
551 | #define RB_NEXT(ptr, member) \ | ||
552 | container_of_or_null(rb_next(&(ptr)->member), typeof(*ptr), member) | ||
553 | |||
554 | #define RB_PREV(ptr, member) \ | ||
555 | container_of_or_null(rb_prev(&(ptr)->member), typeof(*ptr), member) | ||
556 | |||
557 | /* Does linear interpolation between powers of two */ | ||
558 | static inline unsigned fract_exp_two(unsigned x, unsigned fract_bits) | ||
559 | { | ||
560 | unsigned fract = x & ~(~0 << fract_bits); | ||
561 | |||
562 | x >>= fract_bits; | ||
563 | x = 1 << x; | ||
564 | x += (x * fract) >> fract_bits; | ||
565 | |||
566 | return x; | ||
567 | } | ||
568 | |||
569 | #define bio_end(bio) ((bio)->bi_sector + bio_sectors(bio)) | ||
570 | |||
571 | void bio_map(struct bio *bio, void *base); | ||
572 | |||
573 | int bio_alloc_pages(struct bio *bio, gfp_t gfp); | ||
574 | |||
575 | static inline sector_t bdev_sectors(struct block_device *bdev) | ||
576 | { | ||
577 | return bdev->bd_inode->i_size >> 9; | ||
578 | } | ||
579 | |||
580 | #define closure_bio_submit(bio, cl, dev) \ | ||
581 | do { \ | ||
582 | closure_get(cl); \ | ||
583 | bch_generic_make_request(bio, &(dev)->bio_split_hook); \ | ||
584 | } while (0) | ||
585 | |||
586 | uint64_t crc64_update(uint64_t, const void *, size_t); | ||
587 | uint64_t crc64(const void *, size_t); | ||
588 | |||
589 | #endif /* _BCACHE_UTIL_H */ | ||