@@ -511,6 +511,172 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
511
511
}
512
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
681
* bitmap_find_free_region - find a contiguous aligned mem region
516
682
* @bitmap: an array of unsigned longs corresponding to the bitmap
0 commit comments