GNU Linux-libre 4.19.207-gnu1
[releases.git] / fs / xfs / libxfs / xfs_bit.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include "xfs.h"
7 #include "xfs_log_format.h"
8 #include "xfs_bit.h"
9
10 /*
11  * XFS bit manipulation routines, used in non-realtime code.
12  */
13
14 /*
15  * Return whether bitmap is empty.
16  * Size is number of words in the bitmap, which is padded to word boundary
17  * Returns 1 for empty, 0 for non-empty.
18  */
19 int
20 xfs_bitmap_empty(uint *map, uint size)
21 {
22         uint i;
23
24         for (i = 0; i < size; i++) {
25                 if (map[i] != 0)
26                         return 0;
27         }
28
29         return 1;
30 }
31
32 /*
33  * Count the number of contiguous bits set in the bitmap starting with bit
34  * start_bit.  Size is the size of the bitmap in words.
35  */
36 int
37 xfs_contig_bits(uint *map, uint size, uint start_bit)
38 {
39         uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
40         uint result = 0;
41         uint tmp;
42
43         size <<= BIT_TO_WORD_SHIFT;
44
45         ASSERT(start_bit < size);
46         size -= start_bit & ~(NBWORD - 1);
47         start_bit &= (NBWORD - 1);
48         if (start_bit) {
49                 tmp = *p++;
50                 /* set to one first offset bits prior to start */
51                 tmp |= (~0U >> (NBWORD-start_bit));
52                 if (tmp != ~0U)
53                         goto found;
54                 result += NBWORD;
55                 size -= NBWORD;
56         }
57         while (size) {
58                 if ((tmp = *p++) != ~0U)
59                         goto found;
60                 result += NBWORD;
61                 size -= NBWORD;
62         }
63         return result - start_bit;
64 found:
65         return result + ffz(tmp) - start_bit;
66 }
67
68 /*
69  * This takes the bit number to start looking from and
70  * returns the next set bit from there.  It returns -1
71  * if there are no more bits set or the start bit is
72  * beyond the end of the bitmap.
73  *
74  * Size is the number of words, not bytes, in the bitmap.
75  */
76 int xfs_next_bit(uint *map, uint size, uint start_bit)
77 {
78         uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
79         uint result = start_bit & ~(NBWORD - 1);
80         uint tmp;
81
82         size <<= BIT_TO_WORD_SHIFT;
83
84         if (start_bit >= size)
85                 return -1;
86         size -= result;
87         start_bit &= (NBWORD - 1);
88         if (start_bit) {
89                 tmp = *p++;
90                 /* set to zero first offset bits prior to start */
91                 tmp &= (~0U << start_bit);
92                 if (tmp != 0U)
93                         goto found;
94                 result += NBWORD;
95                 size -= NBWORD;
96         }
97         while (size) {
98                 if ((tmp = *p++) != 0U)
99                         goto found;
100                 result += NBWORD;
101                 size -= NBWORD;
102         }
103         return -1;
104 found:
105         return result + ffs(tmp) - 1;
106 }