diff options
| author | Anton Altaparmakov <aia21@cantab.net> | 2005-10-31 05:06:46 -0500 |
|---|---|---|
| committer | Anton Altaparmakov <aia21@cantab.net> | 2005-10-31 05:06:46 -0500 |
| commit | 1f04c0a24b2f3cfe89c802a24396263623e3512d (patch) | |
| tree | d7e2216b6e65b833c0c2b79b478d13ce17dbf296 /lib/bitmap.c | |
| parent | 07b188ab773e183871e57b33ae37bf635c9f12ba (diff) | |
| parent | e2f2e58e7968f8446b1078a20a18bf8ea12b4fbc (diff) | |
Merge branch 'master' of /usr/src/ntfs-2.6/
Diffstat (limited to 'lib/bitmap.c')
| -rw-r--r-- | lib/bitmap.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/lib/bitmap.c b/lib/bitmap.c index fb9371fdd44a..23d3b1147fe9 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
| @@ -511,6 +511,172 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) | |||
| 511 | } | 511 | } |
| 512 | EXPORT_SYMBOL(bitmap_parselist); | 512 | EXPORT_SYMBOL(bitmap_parselist); |
| 513 | 513 | ||
| 514 | /* | ||
| 515 | * bitmap_pos_to_ord(buf, pos, bits) | ||
| 516 | * @buf: pointer to a bitmap | ||
| 517 | * @pos: a bit position in @buf (0 <= @pos < @bits) | ||
| 518 | * @bits: number of valid bit positions in @buf | ||
| 519 | * | ||
| 520 | * Map the bit at position @pos in @buf (of length @bits) to the | ||
| 521 | * ordinal of which set bit it is. If it is not set or if @pos | ||
| 522 | * is not a valid bit position, map to zero (0). | ||
| 523 | * | ||
| 524 | * If for example, just bits 4 through 7 are set in @buf, then @pos | ||
| 525 | * values 4 through 7 will get mapped to 0 through 3, respectively, | ||
| 526 | * and other @pos values will get mapped to 0. When @pos value 7 | ||
| 527 | * gets mapped to (returns) @ord value 3 in this example, that means | ||
| 528 | * that bit 7 is the 3rd (starting with 0th) set bit in @buf. | ||
| 529 | * | ||
| 530 | * The bit positions 0 through @bits are valid positions in @buf. | ||
| 531 | */ | ||
| 532 | static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits) | ||
| 533 | { | ||
| 534 | int ord = 0; | ||
| 535 | |||
| 536 | if (pos >= 0 && pos < bits) { | ||
| 537 | int i; | ||
| 538 | |||
| 539 | for (i = find_first_bit(buf, bits); | ||
| 540 | i < pos; | ||
| 541 | i = find_next_bit(buf, bits, i + 1)) | ||
| 542 | ord++; | ||
| 543 | if (i > pos) | ||
| 544 | ord = 0; | ||
| 545 | } | ||
| 546 | return ord; | ||
| 547 | } | ||
| 548 | |||
| 549 | /** | ||
| 550 | * bitmap_ord_to_pos(buf, ord, bits) | ||
| 551 | * @buf: pointer to bitmap | ||
| 552 | * @ord: ordinal bit position (n-th set bit, n >= 0) | ||
| 553 | * @bits: number of valid bit positions in @buf | ||
| 554 | * | ||
| 555 | * Map the ordinal offset of bit @ord in @buf to its position in @buf. | ||
| 556 | * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0). | ||
| 557 | * | ||
| 558 | * If for example, just bits 4 through 7 are set in @buf, then @ord | ||
| 559 | * values 0 through 3 will get mapped to 4 through 7, respectively, | ||
| 560 | * and all other @ord valuds will get mapped to 0. When @ord value 3 | ||
| 561 | * gets mapped to (returns) @pos value 7 in this example, that means | ||
| 562 | * that the 3rd set bit (starting with 0th) is at position 7 in @buf. | ||
| 563 | * | ||
| 564 | * The bit positions 0 through @bits are valid positions in @buf. | ||
| 565 | */ | ||
| 566 | static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits) | ||
| 567 | { | ||
| 568 | int pos = 0; | ||
| 569 | |||
| 570 | if (ord >= 0 && ord < bits) { | ||
| 571 | int i; | ||
| 572 | |||
| 573 | for (i = find_first_bit(buf, bits); | ||
| 574 | i < bits && ord > 0; | ||
| 575 | i = find_next_bit(buf, bits, i + 1)) | ||
| 576 | ord--; | ||
| 577 | if (i < bits && ord == 0) | ||
| 578 | pos = i; | ||
| 579 | } | ||
| 580 | |||
| 581 | return pos; | ||
| 582 | } | ||
| 583 | |||
| 584 | /** | ||
| 585 | * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap | ||
| 586 | * @src: subset to be remapped | ||
| 587 | * @dst: remapped result | ||
| 588 | * @old: defines domain of map | ||
| 589 | * @new: defines range of map | ||
| 590 | * @bits: number of bits in each of these bitmaps | ||
| 591 | * | ||
| 592 | * Let @old and @new define a mapping of bit positions, such that | ||
| 593 | * whatever position is held by the n-th set bit in @old is mapped | ||
| 594 | * to the n-th set bit in @new. In the more general case, allowing | ||
| 595 | * for the possibility that the weight 'w' of @new is less than the | ||
| 596 | * weight of @old, map the position of the n-th set bit in @old to | ||
| 597 | * the position of the m-th set bit in @new, where m == n % w. | ||
| 598 | * | ||
| 599 | * If either of the @old and @new bitmaps are empty, or if@src and @dst | ||
| 600 | * point to the same location, then this routine does nothing. | ||
| 601 | * | ||
| 602 | * The positions of unset bits in @old are mapped to the position of | ||
| 603 | * the first set bit in @new. | ||
| 604 | * | ||
| 605 | * Apply the above specified mapping to @src, placing the result in | ||
| 606 | * @dst, clearing any bits previously set in @dst. | ||
| 607 | * | ||
| 608 | * The resulting value of @dst will have either the same weight as | ||
| 609 | * @src, or less weight in the general case that the mapping wasn't | ||
| 610 | * injective due to the weight of @new being less than that of @old. | ||
| 611 | * The resulting value of @dst will never have greater weight than | ||
| 612 | * that of @src, except perhaps in the case that one of the above | ||
| 613 | * conditions was not met and this routine just returned. | ||
| 614 | * | ||
| 615 | * For example, lets say that @old has bits 4 through 7 set, and | ||
| 616 | * @new has bits 12 through 15 set. This defines the mapping of bit | ||
| 617 | * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other | ||
| 618 | * bit positions to 12 (the first set bit in @new. So if say @src | ||
| 619 | * comes into this routine with bits 1, 5 and 7 set, then @dst should | ||
| 620 | * leave with bits 12, 13 and 15 set. | ||
| 621 | */ | ||
| 622 | void bitmap_remap(unsigned long *dst, const unsigned long *src, | ||
| 623 | const unsigned long *old, const unsigned long *new, | ||
| 624 | int bits) | ||
| 625 | { | ||
| 626 | int s; | ||
| 627 | |||
| 628 | if (bitmap_weight(old, bits) == 0) | ||
| 629 | return; | ||
| 630 | if (bitmap_weight(new, bits) == 0) | ||
| 631 | return; | ||
| 632 | if (dst == src) /* following doesn't handle inplace remaps */ | ||
| 633 | return; | ||
| 634 | |||
| 635 | bitmap_zero(dst, bits); | ||
| 636 | for (s = find_first_bit(src, bits); | ||
| 637 | s < bits; | ||
| 638 | s = find_next_bit(src, bits, s + 1)) { | ||
| 639 | int x = bitmap_pos_to_ord(old, s, bits); | ||
| 640 | int y = bitmap_ord_to_pos(new, x, bits); | ||
| 641 | set_bit(y, dst); | ||
| 642 | } | ||
| 643 | } | ||
| 644 | EXPORT_SYMBOL(bitmap_remap); | ||
| 645 | |||
| 646 | /** | ||
| 647 | * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit | ||
| 648 | * @oldbit - bit position to be mapped | ||
| 649 | * @old: defines domain of map | ||
| 650 | * @new: defines range of map | ||
| 651 | * @bits: number of bits in each of these bitmaps | ||
| 652 | * | ||
| 653 | * Let @old and @new define a mapping of bit positions, such that | ||
| 654 | * whatever position is held by the n-th set bit in @old is mapped | ||
| 655 | * to the n-th set bit in @new. In the more general case, allowing | ||
| 656 | * for the possibility that the weight 'w' of @new is less than the | ||
| 657 | * weight of @old, map the position of the n-th set bit in @old to | ||
| 658 | * the position of the m-th set bit in @new, where m == n % w. | ||
| 659 | * | ||
| 660 | * The positions of unset bits in @old are mapped to the position of | ||
| 661 | * the first set bit in @new. | ||
| 662 | * | ||
| 663 | * Apply the above specified mapping to bit position @oldbit, returning | ||
| 664 | * the new bit position. | ||
| 665 | * | ||
| 666 | * For example, lets say that @old has bits 4 through 7 set, and | ||
| 667 | * @new has bits 12 through 15 set. This defines the mapping of bit | ||
| 668 | * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other | ||
| 669 | * bit positions to 12 (the first set bit in @new. So if say @oldbit | ||
| 670 | * is 5, then this routine returns 13. | ||
| 671 | */ | ||
| 672 | int bitmap_bitremap(int oldbit, const unsigned long *old, | ||
| 673 | const unsigned long *new, int bits) | ||
| 674 | { | ||
| 675 | int x = bitmap_pos_to_ord(old, oldbit, bits); | ||
| 676 | return bitmap_ord_to_pos(new, x, bits); | ||
| 677 | } | ||
| 678 | EXPORT_SYMBOL(bitmap_bitremap); | ||
| 679 | |||
| 514 | /** | 680 | /** |
| 515 | * bitmap_find_free_region - find a contiguous aligned mem region | 681 | * bitmap_find_free_region - find a contiguous aligned mem region |
| 516 | * @bitmap: an array of unsigned longs corresponding to the bitmap | 682 | * @bitmap: an array of unsigned longs corresponding to the bitmap |
