activemap.c (223654) | activemap.c (225787) |
---|---|
1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sbin/hastd/activemap.c 223654 2011-06-28 20:57:54Z trociny $"); | 31__FBSDID("$FreeBSD: head/sbin/hastd/activemap.c 225787 2011-09-27 08:50:37Z pjd $"); |
32 33#include <sys/param.h> /* powerof2() */ 34#include <sys/queue.h> 35 | 32 33#include <sys/param.h> /* powerof2() */ 34#include <sys/queue.h> 35 |
36#include <assert.h> | |
37#include <bitstring.h> 38#include <errno.h> 39#include <stdint.h> 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43 | 36#include <bitstring.h> 37#include <errno.h> 38#include <stdint.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42 |
44#include <activemap.h> | 43#include <pjdlog.h> |
45 | 44 |
45#include "activemap.h" 46 47#ifndef PJDLOG_ASSERT 48#include <assert.h> 49#define PJDLOG_ASSERT(...) assert(__VA_ARGS__) 50#endif 51 |
|
46#define ACTIVEMAP_MAGIC 0xac71e4 47struct activemap { 48 int am_magic; /* Magic value. */ 49 off_t am_mediasize; /* Media size in bytes. */ 50 uint32_t am_extentsize; /* Extent size in bytes, 51 must be power of 2. */ 52 uint8_t am_extentshift;/* 2 ^ extentbits == extentsize */ 53 int am_nextents; /* Number of extents. */ --- 34 unchanged lines hidden (view full) --- 88 return (x); 89} 90 91static __inline int 92off2ext(const struct activemap *amp, off_t offset) 93{ 94 int extent; 95 | 52#define ACTIVEMAP_MAGIC 0xac71e4 53struct activemap { 54 int am_magic; /* Magic value. */ 55 off_t am_mediasize; /* Media size in bytes. */ 56 uint32_t am_extentsize; /* Extent size in bytes, 57 must be power of 2. */ 58 uint8_t am_extentshift;/* 2 ^ extentbits == extentsize */ 59 int am_nextents; /* Number of extents. */ --- 34 unchanged lines hidden (view full) --- 94 return (x); 95} 96 97static __inline int 98off2ext(const struct activemap *amp, off_t offset) 99{ 100 int extent; 101 |
96 assert(offset >= 0 && offset < amp->am_mediasize); | 102 PJDLOG_ASSERT(offset >= 0 && offset < amp->am_mediasize); |
97 extent = (offset >> amp->am_extentshift); | 103 extent = (offset >> amp->am_extentshift); |
98 assert(extent >= 0 && extent < amp->am_nextents); | 104 PJDLOG_ASSERT(extent >= 0 && extent < amp->am_nextents); |
99 return (extent); 100} 101 102static __inline off_t 103ext2off(const struct activemap *amp, int extent) 104{ 105 off_t offset; 106 | 105 return (extent); 106} 107 108static __inline off_t 109ext2off(const struct activemap *amp, int extent) 110{ 111 off_t offset; 112 |
107 assert(extent >= 0 && extent < amp->am_nextents); | 113 PJDLOG_ASSERT(extent >= 0 && extent < amp->am_nextents); |
108 offset = ((off_t)extent << amp->am_extentshift); | 114 offset = ((off_t)extent << amp->am_extentshift); |
109 assert(offset >= 0 && offset < amp->am_mediasize); | 115 PJDLOG_ASSERT(offset >= 0 && offset < amp->am_mediasize); |
110 return (offset); 111} 112 113/* 114 * Function calculates number of requests needed to synchronize the given 115 * extent. 116 */ 117static __inline int 118ext2reqs(const struct activemap *amp, int ext) 119{ 120 off_t left; 121 122 if (ext < amp->am_nextents - 1) 123 return (((amp->am_extentsize - 1) / MAXPHYS) + 1); 124 | 116 return (offset); 117} 118 119/* 120 * Function calculates number of requests needed to synchronize the given 121 * extent. 122 */ 123static __inline int 124ext2reqs(const struct activemap *amp, int ext) 125{ 126 off_t left; 127 128 if (ext < amp->am_nextents - 1) 129 return (((amp->am_extentsize - 1) / MAXPHYS) + 1); 130 |
125 assert(ext == amp->am_nextents - 1); | 131 PJDLOG_ASSERT(ext == amp->am_nextents - 1); |
126 left = amp->am_mediasize % amp->am_extentsize; 127 if (left == 0) 128 left = amp->am_extentsize; 129 return (((left - 1) / MAXPHYS) + 1); 130} 131 132/* 133 * Initialize activemap structure and allocate memory for internal needs. 134 * Function returns 0 on success and -1 if any of the allocations failed. 135 */ 136int 137activemap_init(struct activemap **ampp, uint64_t mediasize, uint32_t extentsize, 138 uint32_t sectorsize, uint32_t keepdirty) 139{ 140 struct activemap *amp; 141 | 132 left = amp->am_mediasize % amp->am_extentsize; 133 if (left == 0) 134 left = amp->am_extentsize; 135 return (((left - 1) / MAXPHYS) + 1); 136} 137 138/* 139 * Initialize activemap structure and allocate memory for internal needs. 140 * Function returns 0 on success and -1 if any of the allocations failed. 141 */ 142int 143activemap_init(struct activemap **ampp, uint64_t mediasize, uint32_t extentsize, 144 uint32_t sectorsize, uint32_t keepdirty) 145{ 146 struct activemap *amp; 147 |
142 assert(ampp != NULL); 143 assert(mediasize > 0); 144 assert(extentsize > 0); 145 assert(powerof2(extentsize)); 146 assert(sectorsize > 0); 147 assert(powerof2(sectorsize)); 148 assert(keepdirty > 0); | 148 PJDLOG_ASSERT(ampp != NULL); 149 PJDLOG_ASSERT(mediasize > 0); 150 PJDLOG_ASSERT(extentsize > 0); 151 PJDLOG_ASSERT(powerof2(extentsize)); 152 PJDLOG_ASSERT(sectorsize > 0); 153 PJDLOG_ASSERT(powerof2(sectorsize)); 154 PJDLOG_ASSERT(keepdirty > 0); |
149 150 amp = malloc(sizeof(*amp)); 151 if (amp == NULL) 152 return (-1); 153 154 amp->am_mediasize = mediasize; 155 amp->am_nkeepdirty_limit = keepdirty; 156 amp->am_extentsize = extentsize; --- 63 unchanged lines hidden (view full) --- 220 return (false); 221 } 222 /* 223 * Add new element, but first remove the most unused one if 224 * we have too many. 225 */ 226 if (amp->am_nkeepdirty >= amp->am_nkeepdirty_limit) { 227 kd = TAILQ_LAST(&->am_keepdirty, skeepdirty); | 155 156 amp = malloc(sizeof(*amp)); 157 if (amp == NULL) 158 return (-1); 159 160 amp->am_mediasize = mediasize; 161 amp->am_nkeepdirty_limit = keepdirty; 162 amp->am_extentsize = extentsize; --- 63 unchanged lines hidden (view full) --- 226 return (false); 227 } 228 /* 229 * Add new element, but first remove the most unused one if 230 * we have too many. 231 */ 232 if (amp->am_nkeepdirty >= amp->am_nkeepdirty_limit) { 233 kd = TAILQ_LAST(&->am_keepdirty, skeepdirty); |
228 assert(kd != NULL); | 234 PJDLOG_ASSERT(kd != NULL); |
229 TAILQ_REMOVE(&->am_keepdirty, kd, kd_next); 230 amp->am_nkeepdirty--; | 235 TAILQ_REMOVE(&->am_keepdirty, kd, kd_next); 236 amp->am_nkeepdirty--; |
231 assert(amp->am_nkeepdirty > 0); | 237 PJDLOG_ASSERT(amp->am_nkeepdirty > 0); |
232 } 233 if (kd == NULL) 234 kd = malloc(sizeof(*kd)); 235 /* We can ignore allocation failure. */ 236 if (kd != NULL) { 237 kd->kd_extent = extent; 238 amp->am_nkeepdirty++; 239 TAILQ_INSERT_HEAD(&->am_keepdirty, kd, kd_next); --- 16 unchanged lines hidden (view full) --- 256{ 257 struct keepdirty *kd; 258 259 while ((kd = TAILQ_FIRST(&->am_keepdirty)) != NULL) { 260 TAILQ_REMOVE(&->am_keepdirty, kd, kd_next); 261 amp->am_nkeepdirty--; 262 free(kd); 263 } | 238 } 239 if (kd == NULL) 240 kd = malloc(sizeof(*kd)); 241 /* We can ignore allocation failure. */ 242 if (kd != NULL) { 243 kd->kd_extent = extent; 244 amp->am_nkeepdirty++; 245 TAILQ_INSERT_HEAD(&->am_keepdirty, kd, kd_next); --- 16 unchanged lines hidden (view full) --- 262{ 263 struct keepdirty *kd; 264 265 while ((kd = TAILQ_FIRST(&->am_keepdirty)) != NULL) { 266 TAILQ_REMOVE(&->am_keepdirty, kd, kd_next); 267 amp->am_nkeepdirty--; 268 free(kd); 269 } |
264 assert(amp->am_nkeepdirty == 0); | 270 PJDLOG_ASSERT(amp->am_nkeepdirty == 0); |
265} 266 267/* 268 * Function frees resources allocated by activemap_init() function. 269 */ 270void 271activemap_free(struct activemap *amp) 272{ 273 | 271} 272 273/* 274 * Function frees resources allocated by activemap_init() function. 275 */ 276void 277activemap_free(struct activemap *amp) 278{ 279 |
274 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 280 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
275 276 amp->am_magic = 0; 277 278 keepdirty_free(amp); 279 free(amp->am_memtab); 280 free(amp->am_diskmap); 281 free(amp->am_memmap); 282 free(amp->am_syncmap); --- 5 unchanged lines hidden (view full) --- 288 */ 289bool 290activemap_write_start(struct activemap *amp, off_t offset, off_t length) 291{ 292 bool modified; 293 off_t end; 294 int ext; 295 | 281 282 amp->am_magic = 0; 283 284 keepdirty_free(amp); 285 free(amp->am_memtab); 286 free(amp->am_diskmap); 287 free(amp->am_memmap); 288 free(amp->am_syncmap); --- 5 unchanged lines hidden (view full) --- 294 */ 295bool 296activemap_write_start(struct activemap *amp, off_t offset, off_t length) 297{ 298 bool modified; 299 off_t end; 300 int ext; 301 |
296 assert(amp->am_magic == ACTIVEMAP_MAGIC); 297 assert(length > 0); | 302 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); 303 PJDLOG_ASSERT(length > 0); |
298 299 modified = false; 300 end = offset + length - 1; 301 302 for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { 303 /* 304 * If the number of pending writes is increased from 0, 305 * we have to mark the extent as dirty also in on-disk bitmap. 306 * By returning true we inform the caller that on-disk bitmap 307 * was modified and has to be flushed to disk. 308 */ 309 if (amp->am_memtab[ext]++ == 0) { | 304 305 modified = false; 306 end = offset + length - 1; 307 308 for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { 309 /* 310 * If the number of pending writes is increased from 0, 311 * we have to mark the extent as dirty also in on-disk bitmap. 312 * By returning true we inform the caller that on-disk bitmap 313 * was modified and has to be flushed to disk. 314 */ 315 if (amp->am_memtab[ext]++ == 0) { |
310 assert(!bit_test(amp->am_memmap, ext)); | 316 PJDLOG_ASSERT(!bit_test(amp->am_memmap, ext)); |
311 bit_set(amp->am_memmap, ext); 312 amp->am_ndirty++; 313 } 314 if (keepdirty_add(amp, ext)) 315 modified = true; 316 } 317 318 return (modified); --- 5 unchanged lines hidden (view full) --- 324 */ 325bool 326activemap_write_complete(struct activemap *amp, off_t offset, off_t length) 327{ 328 bool modified; 329 off_t end; 330 int ext; 331 | 317 bit_set(amp->am_memmap, ext); 318 amp->am_ndirty++; 319 } 320 if (keepdirty_add(amp, ext)) 321 modified = true; 322 } 323 324 return (modified); --- 5 unchanged lines hidden (view full) --- 330 */ 331bool 332activemap_write_complete(struct activemap *amp, off_t offset, off_t length) 333{ 334 bool modified; 335 off_t end; 336 int ext; 337 |
332 assert(amp->am_magic == ACTIVEMAP_MAGIC); 333 assert(length > 0); | 338 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); 339 PJDLOG_ASSERT(length > 0); |
334 335 modified = false; 336 end = offset + length - 1; 337 338 for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { 339 /* 340 * If the number of pending writes goes down to 0, we have to 341 * mark the extent as clean also in on-disk bitmap. 342 * By returning true we inform the caller that on-disk bitmap 343 * was modified and has to be flushed to disk. 344 */ | 340 341 modified = false; 342 end = offset + length - 1; 343 344 for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { 345 /* 346 * If the number of pending writes goes down to 0, we have to 347 * mark the extent as clean also in on-disk bitmap. 348 * By returning true we inform the caller that on-disk bitmap 349 * was modified and has to be flushed to disk. 350 */ |
345 assert(amp->am_memtab[ext] > 0); 346 assert(bit_test(amp->am_memmap, ext)); | 351 PJDLOG_ASSERT(amp->am_memtab[ext] > 0); 352 PJDLOG_ASSERT(bit_test(amp->am_memmap, ext)); |
347 if (--amp->am_memtab[ext] == 0) { 348 bit_clear(amp->am_memmap, ext); 349 amp->am_ndirty--; 350 if (keepdirty_find(amp, ext) == NULL) 351 modified = true; 352 } 353 } 354 --- 5 unchanged lines hidden (view full) --- 360 * It returns true if on-disk metadata should be updated. 361 */ 362bool 363activemap_extent_complete(struct activemap *amp, int extent) 364{ 365 bool modified; 366 int reqs; 367 | 353 if (--amp->am_memtab[ext] == 0) { 354 bit_clear(amp->am_memmap, ext); 355 amp->am_ndirty--; 356 if (keepdirty_find(amp, ext) == NULL) 357 modified = true; 358 } 359 } 360 --- 5 unchanged lines hidden (view full) --- 366 * It returns true if on-disk metadata should be updated. 367 */ 368bool 369activemap_extent_complete(struct activemap *amp, int extent) 370{ 371 bool modified; 372 int reqs; 373 |
368 assert(amp->am_magic == ACTIVEMAP_MAGIC); 369 assert(extent >= 0 && extent < amp->am_nextents); | 374 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); 375 PJDLOG_ASSERT(extent >= 0 && extent < amp->am_nextents); |
370 371 modified = false; 372 373 reqs = ext2reqs(amp, extent); | 376 377 modified = false; 378 379 reqs = ext2reqs(amp, extent); |
374 assert(amp->am_memtab[extent] >= reqs); | 380 PJDLOG_ASSERT(amp->am_memtab[extent] >= reqs); |
375 amp->am_memtab[extent] -= reqs; | 381 amp->am_memtab[extent] -= reqs; |
376 assert(bit_test(amp->am_memmap, extent)); | 382 PJDLOG_ASSERT(bit_test(amp->am_memmap, extent)); |
377 if (amp->am_memtab[extent] == 0) { 378 bit_clear(amp->am_memmap, extent); 379 amp->am_ndirty--; 380 modified = true; 381 } 382 383 return (modified); 384} 385 386/* 387 * Function returns number of dirty regions. 388 */ 389uint64_t 390activemap_ndirty(const struct activemap *amp) 391{ 392 | 383 if (amp->am_memtab[extent] == 0) { 384 bit_clear(amp->am_memmap, extent); 385 amp->am_ndirty--; 386 modified = true; 387 } 388 389 return (modified); 390} 391 392/* 393 * Function returns number of dirty regions. 394 */ 395uint64_t 396activemap_ndirty(const struct activemap *amp) 397{ 398 |
393 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 399 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
394 395 return (amp->am_ndirty); 396} 397 398/* 399 * Function compare on-disk bitmap and in-memory bitmap and returns true if 400 * they differ and should be flushed to the disk. 401 */ 402bool 403activemap_differ(const struct activemap *amp) 404{ 405 | 400 401 return (amp->am_ndirty); 402} 403 404/* 405 * Function compare on-disk bitmap and in-memory bitmap and returns true if 406 * they differ and should be flushed to the disk. 407 */ 408bool 409activemap_differ(const struct activemap *amp) 410{ 411 |
406 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 412 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
407 408 return (memcmp(amp->am_diskmap, amp->am_memmap, 409 amp->am_mapsize) != 0); 410} 411 412/* 413 * Function returns number of bytes used by bitmap. 414 */ 415size_t 416activemap_size(const struct activemap *amp) 417{ 418 | 413 414 return (memcmp(amp->am_diskmap, amp->am_memmap, 415 amp->am_mapsize) != 0); 416} 417 418/* 419 * Function returns number of bytes used by bitmap. 420 */ 421size_t 422activemap_size(const struct activemap *amp) 423{ 424 |
419 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 425 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
420 421 return (amp->am_mapsize); 422} 423 424/* 425 * Function returns number of bytes needed for storing on-disk bitmap. 426 * This is the same as activemap_size(), but rounded up to sector size. 427 */ 428size_t 429activemap_ondisk_size(const struct activemap *amp) 430{ 431 | 426 427 return (amp->am_mapsize); 428} 429 430/* 431 * Function returns number of bytes needed for storing on-disk bitmap. 432 * This is the same as activemap_size(), but rounded up to sector size. 433 */ 434size_t 435activemap_ondisk_size(const struct activemap *amp) 436{ 437 |
432 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 438 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
433 434 return (amp->am_diskmapsize); 435} 436 437/* 438 * Function copies the given buffer read from disk to the internal bitmap. 439 */ 440void 441activemap_copyin(struct activemap *amp, const unsigned char *buf, size_t size) 442{ 443 int ext; 444 | 439 440 return (amp->am_diskmapsize); 441} 442 443/* 444 * Function copies the given buffer read from disk to the internal bitmap. 445 */ 446void 447activemap_copyin(struct activemap *amp, const unsigned char *buf, size_t size) 448{ 449 int ext; 450 |
445 assert(amp->am_magic == ACTIVEMAP_MAGIC); 446 assert(size >= amp->am_mapsize); | 451 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); 452 PJDLOG_ASSERT(size >= amp->am_mapsize); |
447 448 memcpy(amp->am_diskmap, buf, amp->am_mapsize); 449 memcpy(amp->am_memmap, buf, amp->am_mapsize); 450 memcpy(amp->am_syncmap, buf, amp->am_mapsize); 451 452 bit_ffs(amp->am_memmap, amp->am_nextents, &ext); 453 if (ext == -1) { 454 /* There are no dirty extents, so we can leave now. */ --- 21 unchanged lines hidden (view full) --- 476 * Function merges the given bitmap with existing one. 477 */ 478void 479activemap_merge(struct activemap *amp, const unsigned char *buf, size_t size) 480{ 481 bitstr_t *remmap = __DECONST(bitstr_t *, buf); 482 int ext; 483 | 453 454 memcpy(amp->am_diskmap, buf, amp->am_mapsize); 455 memcpy(amp->am_memmap, buf, amp->am_mapsize); 456 memcpy(amp->am_syncmap, buf, amp->am_mapsize); 457 458 bit_ffs(amp->am_memmap, amp->am_nextents, &ext); 459 if (ext == -1) { 460 /* There are no dirty extents, so we can leave now. */ --- 21 unchanged lines hidden (view full) --- 482 * Function merges the given bitmap with existing one. 483 */ 484void 485activemap_merge(struct activemap *amp, const unsigned char *buf, size_t size) 486{ 487 bitstr_t *remmap = __DECONST(bitstr_t *, buf); 488 int ext; 489 |
484 assert(amp->am_magic == ACTIVEMAP_MAGIC); 485 assert(size >= amp->am_mapsize); | 490 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); 491 PJDLOG_ASSERT(size >= amp->am_mapsize); |
486 487 bit_ffs(remmap, amp->am_nextents, &ext); 488 if (ext == -1) { 489 /* There are no dirty extents, so we can leave now. */ 490 return; 491 } 492 /* 493 * We have dirty extents and we want them to stay that way until --- 22 unchanged lines hidden (view full) --- 516 517/* 518 * Function returns pointer to internal bitmap that should be written to disk. 519 */ 520const unsigned char * 521activemap_bitmap(struct activemap *amp, size_t *sizep) 522{ 523 | 492 493 bit_ffs(remmap, amp->am_nextents, &ext); 494 if (ext == -1) { 495 /* There are no dirty extents, so we can leave now. */ 496 return; 497 } 498 /* 499 * We have dirty extents and we want them to stay that way until --- 22 unchanged lines hidden (view full) --- 522 523/* 524 * Function returns pointer to internal bitmap that should be written to disk. 525 */ 526const unsigned char * 527activemap_bitmap(struct activemap *amp, size_t *sizep) 528{ 529 |
524 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 530 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
525 526 if (sizep != NULL) 527 *sizep = amp->am_diskmapsize; 528 memcpy(amp->am_diskmap, amp->am_memmap, amp->am_mapsize); 529 keepdirty_fill(amp); 530 return ((const unsigned char *)amp->am_diskmap); 531} 532 533/* 534 * Function calculates size needed to store bitmap on disk. 535 */ 536size_t 537activemap_calc_ondisk_size(uint64_t mediasize, uint32_t extentsize, 538 uint32_t sectorsize) 539{ 540 uint64_t nextents, mapsize; 541 | 531 532 if (sizep != NULL) 533 *sizep = amp->am_diskmapsize; 534 memcpy(amp->am_diskmap, amp->am_memmap, amp->am_mapsize); 535 keepdirty_fill(amp); 536 return ((const unsigned char *)amp->am_diskmap); 537} 538 539/* 540 * Function calculates size needed to store bitmap on disk. 541 */ 542size_t 543activemap_calc_ondisk_size(uint64_t mediasize, uint32_t extentsize, 544 uint32_t sectorsize) 545{ 546 uint64_t nextents, mapsize; 547 |
542 assert(mediasize > 0); 543 assert(extentsize > 0); 544 assert(powerof2(extentsize)); 545 assert(sectorsize > 0); 546 assert(powerof2(sectorsize)); | 548 PJDLOG_ASSERT(mediasize > 0); 549 PJDLOG_ASSERT(extentsize > 0); 550 PJDLOG_ASSERT(powerof2(extentsize)); 551 PJDLOG_ASSERT(sectorsize > 0); 552 PJDLOG_ASSERT(powerof2(sectorsize)); |
547 548 nextents = ((mediasize - 1) / extentsize) + 1; 549 mapsize = sizeof(bitstr_t) * bitstr_size(nextents); 550 return (roundup2(mapsize, sectorsize)); 551} 552 553/* 554 * Set synchronization offset to the first dirty extent. 555 */ 556void 557activemap_sync_rewind(struct activemap *amp) 558{ 559 int ext; 560 | 553 554 nextents = ((mediasize - 1) / extentsize) + 1; 555 mapsize = sizeof(bitstr_t) * bitstr_size(nextents); 556 return (roundup2(mapsize, sectorsize)); 557} 558 559/* 560 * Set synchronization offset to the first dirty extent. 561 */ 562void 563activemap_sync_rewind(struct activemap *amp) 564{ 565 int ext; 566 |
561 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 567 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
562 563 bit_ffs(amp->am_syncmap, amp->am_nextents, &ext); 564 if (ext == -1) { 565 /* There are no extents to synchronize. */ 566 amp->am_syncoff = -2; 567 return; 568 } 569 /* --- 6 unchanged lines hidden (view full) --- 576 * Return next offset of where we should synchronize. 577 */ 578off_t 579activemap_sync_offset(struct activemap *amp, off_t *lengthp, int *syncextp) 580{ 581 off_t syncoff, left; 582 int ext; 583 | 568 569 bit_ffs(amp->am_syncmap, amp->am_nextents, &ext); 570 if (ext == -1) { 571 /* There are no extents to synchronize. */ 572 amp->am_syncoff = -2; 573 return; 574 } 575 /* --- 6 unchanged lines hidden (view full) --- 582 * Return next offset of where we should synchronize. 583 */ 584off_t 585activemap_sync_offset(struct activemap *amp, off_t *lengthp, int *syncextp) 586{ 587 off_t syncoff, left; 588 int ext; 589 |
584 assert(amp->am_magic == ACTIVEMAP_MAGIC); 585 assert(lengthp != NULL); 586 assert(syncextp != NULL); | 590 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); 591 PJDLOG_ASSERT(lengthp != NULL); 592 PJDLOG_ASSERT(syncextp != NULL); |
587 588 *syncextp = -1; 589 590 if (amp->am_syncoff == -2) 591 return (-1); 592 593 if (amp->am_syncoff >= 0 && 594 (amp->am_syncoff + MAXPHYS >= amp->am_mediasize || --- 32 unchanged lines hidden (view full) --- 627 syncoff = amp->am_syncoff; 628 left = ext2off(amp, off2ext(amp, syncoff)) + 629 amp->am_extentsize - syncoff; 630 if (syncoff + left > amp->am_mediasize) 631 left = amp->am_mediasize - syncoff; 632 if (left > MAXPHYS) 633 left = MAXPHYS; 634 | 593 594 *syncextp = -1; 595 596 if (amp->am_syncoff == -2) 597 return (-1); 598 599 if (amp->am_syncoff >= 0 && 600 (amp->am_syncoff + MAXPHYS >= amp->am_mediasize || --- 32 unchanged lines hidden (view full) --- 633 syncoff = amp->am_syncoff; 634 left = ext2off(amp, off2ext(amp, syncoff)) + 635 amp->am_extentsize - syncoff; 636 if (syncoff + left > amp->am_mediasize) 637 left = amp->am_mediasize - syncoff; 638 if (left > MAXPHYS) 639 left = MAXPHYS; 640 |
635 assert(left >= 0 && left <= MAXPHYS); 636 assert(syncoff >= 0 && syncoff < amp->am_mediasize); 637 assert(syncoff + left >= 0 && syncoff + left <= amp->am_mediasize); | 641 PJDLOG_ASSERT(left >= 0 && left <= MAXPHYS); 642 PJDLOG_ASSERT(syncoff >= 0 && syncoff < amp->am_mediasize); 643 PJDLOG_ASSERT(syncoff + left >= 0 && 644 syncoff + left <= amp->am_mediasize); |
638 639 *lengthp = left; 640 return (syncoff); 641} 642 643/* 644 * Mark extent(s) containing the given region for synchronization. 645 * Most likely one of the components is unavailable. 646 */ 647bool 648activemap_need_sync(struct activemap *amp, off_t offset, off_t length) 649{ 650 bool modified; 651 off_t end; 652 int ext; 653 | 645 646 *lengthp = left; 647 return (syncoff); 648} 649 650/* 651 * Mark extent(s) containing the given region for synchronization. 652 * Most likely one of the components is unavailable. 653 */ 654bool 655activemap_need_sync(struct activemap *amp, off_t offset, off_t length) 656{ 657 bool modified; 658 off_t end; 659 int ext; 660 |
654 assert(amp->am_magic == ACTIVEMAP_MAGIC); | 661 PJDLOG_ASSERT(amp->am_magic == ACTIVEMAP_MAGIC); |
655 656 modified = false; 657 end = offset + length - 1; 658 659 for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { 660 if (bit_test(amp->am_syncmap, ext)) { 661 /* Already marked for synchronization. */ | 662 663 modified = false; 664 end = offset + length - 1; 665 666 for (ext = off2ext(amp, offset); ext <= off2ext(amp, end); ext++) { 667 if (bit_test(amp->am_syncmap, ext)) { 668 /* Already marked for synchronization. */ |
662 assert(bit_test(amp->am_memmap, ext)); | 669 PJDLOG_ASSERT(bit_test(amp->am_memmap, ext)); |
663 continue; 664 } 665 bit_set(amp->am_syncmap, ext); 666 if (!bit_test(amp->am_memmap, ext)) { 667 bit_set(amp->am_memmap, ext); 668 amp->am_ndirty++; 669 } 670 amp->am_memtab[ext] += ext2reqs(amp, ext); --- 24 unchanged lines hidden --- | 670 continue; 671 } 672 bit_set(amp->am_syncmap, ext); 673 if (!bit_test(amp->am_memmap, ext)) { 674 bit_set(amp->am_memmap, ext); 675 amp->am_ndirty++; 676 } 677 amp->am_memtab[ext] += ext2reqs(amp, ext); --- 24 unchanged lines hidden --- |