Release 4.12 lib/bitmap.c
/*
* lib/bitmap.c
* Helper functions for bitmap.h.
*
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
#include <linux/export.h>
#include <linux/thread_info.h>
#include <linux/ctype.h>
#include <linux/errno.h>
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <asm/page.h>
/*
* bitmaps provide an array of bits, implemented using an an
* array of unsigned longs. The number of valid bits in a
* given bitmap does _not_ need to be an exact multiple of
* BITS_PER_LONG.
*
* The possible unused bits in the last, partially used word
* of a bitmap are 'don't care'. The implementation makes
* no particular effort to keep them zero. It ensures that
* their value will not affect the results of any operation.
* The bitmap operations that return Boolean (bitmap_empty,
* for example) or scalar (bitmap_weight, for example) results
* carefully filter out these unused bits from impacting their
* results.
*
* These operations actually hold to a slightly stronger rule:
* if you don't input any bitmaps to these ops that have some
* unused bits set, then they won't output any set unused bits
* in output bitmaps.
*
* The byte ordering of bitmaps is more natural on little
* endian architectures. See the big-endian headers
* include/asm-ppc64/bitops.h and include/asm-s390/bitops.h
* for the best explanations of this ordering.
*/
int __bitmap_equal(const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int bits)
{
unsigned int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k)
if (bitmap1[k] != bitmap2[k])
return 0;
if (bits % BITS_PER_LONG)
if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
return 0;
return 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 88 | 97.78% | 3 | 75.00% |
Rasmus Villemoes | 2 | 2.22% | 1 | 25.00% |
Total | 90 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL(__bitmap_equal);
void __bitmap_complement(unsigned long *dst, const unsigned long *src, unsigned int bits)
{
unsigned int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k)
dst[k] = ~src[k];
if (bits % BITS_PER_LONG)
dst[k] = ~src[k];
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 69 | 97.18% | 4 | 80.00% |
Rasmus Villemoes | 2 | 2.82% | 1 | 20.00% |
Total | 71 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(__bitmap_complement);
/**
* __bitmap_shift_right - logical right shift of the bits in a bitmap
* @dst : destination bitmap
* @src : source bitmap
* @shift : shift by this many bits
* @nbits : bitmap size, in bits
*
* Shifting right (dividing) means moving bits in the MS -> LS bit
* direction. Zeros are fed into the vacated MS positions and the
* LS bits shifted off the bottom are lost.
*/
void __bitmap_shift_right(unsigned long *dst, const unsigned long *src,
unsigned shift, unsigned nbits)
{
unsigned k, lim = BITS_TO_LONGS(nbits);
unsigned off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
for (k = 0; off + k < lim; ++k) {
unsigned long upper, lower;
/*
* If shift is not word aligned, take lower rem bits of
* word above and make them the top rem bits of result.
*/
if (!rem || off + k + 1 >= lim)
upper = 0;
else {
upper = src[off + k + 1];
if (off + k + 1 == lim - 1)
upper &= mask;
upper <<= (BITS_PER_LONG - rem);
}
lower = src[off + k];
if (off + k == lim - 1)
lower &= mask;
lower >>= rem;
dst[k] = lower | upper;
}
if (off)
memset(&dst[lim - off], 0, off*sizeof(unsigned long));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 165 | 85.05% | 4 | 50.00% |
Rasmus Villemoes | 22 | 11.34% | 3 | 37.50% |
Jan Kara | 7 | 3.61% | 1 | 12.50% |
Total | 194 | 100.00% | 8 | 100.00% |
EXPORT_SYMBOL(__bitmap_shift_right);
/**
* __bitmap_shift_left - logical left shift of the bits in a bitmap
* @dst : destination bitmap
* @src : source bitmap
* @shift : shift by this many bits
* @nbits : bitmap size, in bits
*
* Shifting left (multiplying) means moving bits in the LS -> MS
* direction. Zeros are fed into the vacated LS bit positions
* and those MS bits shifted off the top are lost.
*/
void __bitmap_shift_left(unsigned long *dst, const unsigned long *src,
unsigned int shift, unsigned int nbits)
{
int k;
unsigned int lim = BITS_TO_LONGS(nbits);
unsigned int off = shift/BITS_PER_LONG, rem = shift % BITS_PER_LONG;
for (k = lim - off - 1; k >= 0; --k) {
unsigned long upper, lower;
/*
* If shift is not word aligned, take upper rem bits of
* word below and make them the bottom rem bits of result.
*/
if (rem && k > 0)
lower = src[k - 1] >> (BITS_PER_LONG - rem);
else
lower = 0;
upper = src[k] << rem;
dst[k + off] = lower | upper;
}
if (off)
memset(dst, 0, off*sizeof(unsigned long));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 118 | 82.52% | 4 | 57.14% |
Rasmus Villemoes | 17 | 11.89% | 2 | 28.57% |
Jan Kara | 8 | 5.59% | 1 | 14.29% |
Total | 143 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL(__bitmap_shift_left);
int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int bits)
{
unsigned int k;
unsigned int lim = bits/BITS_PER_LONG;
unsigned long result = 0;
for (k = 0; k < lim; k++)
result |= (dst[k] = bitmap1[k] & bitmap2[k]);
if (bits % BITS_PER_LONG)
result |= (dst[k] = bitmap1[k] & bitmap2[k] &
BITMAP_LAST_WORD_MASK(bits));
return result != 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 58 | 52.25% | 2 | 40.00% |
Rasmus Villemoes | 37 | 33.33% | 2 | 40.00% |
Linus Torvalds | 16 | 14.41% | 1 | 20.00% |
Total | 111 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(__bitmap_and);
void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int bits)
{
unsigned int k;
unsigned int nr = BITS_TO_LONGS(bits);
for (k = 0; k < nr; k++)
dst[k] = bitmap1[k] | bitmap2[k];
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 64 | 95.52% | 2 | 66.67% |
Rasmus Villemoes | 3 | 4.48% | 1 | 33.33% |
Total | 67 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(__bitmap_or);
void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int bits)
{
unsigned int k;
unsigned int nr = BITS_TO_LONGS(bits);
for (k = 0; k < nr; k++)
dst[k] = bitmap1[k] ^ bitmap2[k];
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 64 | 95.52% | 2 | 66.67% |
Rasmus Villemoes | 3 | 4.48% | 1 | 33.33% |
Total | 67 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(__bitmap_xor);
int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int bits)
{
unsigned int k;
unsigned int lim = bits/BITS_PER_LONG;
unsigned long result = 0;
for (k = 0; k < lim; k++)
result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
if (bits % BITS_PER_LONG)
result |= (dst[k] = bitmap1[k] & ~bitmap2[k] &
BITMAP_LAST_WORD_MASK(bits));
return result != 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 59 | 52.21% | 2 | 40.00% |
Rasmus Villemoes | 38 | 33.63% | 2 | 40.00% |
Linus Torvalds | 16 | 14.16% | 1 | 20.00% |
Total | 113 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(__bitmap_andnot);
int __bitmap_intersects(const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int bits)
{
unsigned int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k)
if (bitmap1[k] & bitmap2[k])
return 1;
if (bits % BITS_PER_LONG)
if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
return 1;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 88 | 97.78% | 2 | 66.67% |
Rasmus Villemoes | 2 | 2.22% | 1 | 33.33% |
Total | 90 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(__bitmap_intersects);
int __bitmap_subset(const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int bits)
{
unsigned int k, lim = bits/BITS_PER_LONG;
for (k = 0; k < lim; ++k)
if (bitmap1[k] & ~bitmap2[k])
return 0;
if (bits % BITS_PER_LONG)
if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
return 0;
return 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 90 | 97.83% | 2 | 66.67% |
Rasmus Villemoes | 2 | 2.17% | 1 | 33.33% |
Total | 92 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(__bitmap_subset);
int __bitmap_weight(const unsigned long *bitmap, unsigned int bits)
{
unsigned int k, lim = bits/BITS_PER_LONG;
int w = 0;
for (k = 0; k < lim; k++)
w += hweight_long(bitmap[k]);
if (bits % BITS_PER_LONG)
w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
return w;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 68 | 88.31% | 2 | 50.00% |
Rasmus Villemoes | 7 | 9.09% | 1 | 25.00% |
Akinobu Mita | 2 | 2.60% | 1 | 25.00% |
Total | 77 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL(__bitmap_weight);
void bitmap_set(unsigned long *map, unsigned int start, int len)
{
unsigned long *p = map + BIT_WORD(start);
const unsigned int size = start + len;
int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
while (len - bits_to_set >= 0) {
*p |= mask_to_set;
len -= bits_to_set;
bits_to_set = BITS_PER_LONG;
mask_to_set = ~0UL;
p++;
}
if (len) {
mask_to_set &= BITMAP_LAST_WORD_MASK(size);
*p |= mask_to_set;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Akinobu Mita | 100 | 93.46% | 1 | 50.00% |
Rasmus Villemoes | 7 | 6.54% | 1 | 50.00% |
Total | 107 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(bitmap_set);
void bitmap_clear(unsigned long *map, unsigned int start, int len)
{
unsigned long *p = map + BIT_WORD(start);
const unsigned int size = start + len;
int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
while (len - bits_to_clear >= 0) {
*p &= ~mask_to_clear;
len -= bits_to_clear;
bits_to_clear = BITS_PER_LONG;
mask_to_clear = ~0UL;
p++;
}
if (len) {
mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
*p &= ~mask_to_clear;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Akinobu Mita | 102 | 93.58% | 1 | 50.00% |
Rasmus Villemoes | 7 | 6.42% | 1 | 50.00% |
Total | 109 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(bitmap_clear);
/**
* bitmap_find_next_zero_area_off - find a contiguous aligned zero area
* @map: The address to base the search on
* @size: The bitmap size in bits
* @start: The bitnumber to start searching at
* @nr: The number of zeroed bits we're looking for
* @align_mask: Alignment mask for zero area
* @align_offset: Alignment offset for zero area.
*
* The @align_mask should be one less than a power of 2; the effect is that
* the bit offset of all zero areas this function finds plus @align_offset
* is multiple of that power of 2.
*/
unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
unsigned long size,
unsigned long start,
unsigned int nr,
unsigned long align_mask,
unsigned long align_offset)
{
unsigned long index, end, i;
again:
index = find_next_zero_bit(map, size, start);
/* Align allocation */
index = __ALIGN_MASK(index + align_offset, align_mask) - align_offset;
end = index + nr;
if (end > size)
return end;
i = find_next_bit(map, end, index);
if (i < end) {
start = i + 1;
goto again;
}
return index;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Akinobu Mita | 103 | 91.96% | 1 | 50.00% |
Michal Nazarewicz | 9 | 8.04% | 1 | 50.00% |
Total | 112 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(bitmap_find_next_zero_area_off);
/*
* Bitmap printing & parsing functions: first version by Nadia Yvette Chambers,
* second version by Paul Jackson, third by Joe Korty.
*/
#define CHUNKSZ 32
#define nbits_to_hold_value(val) fls(val)
#define BASEDEC 10
/* fancier cpuset lists input in decimal */
/**
* __bitmap_parse - convert an ASCII hex string into a bitmap.
* @buf: pointer to buffer containing string.
* @buflen: buffer size in bytes. If string is smaller than this
* then it must be terminated with a \0.
* @is_user: location of buffer, 0 indicates kernel space
* @maskp: pointer to bitmap array that will contain result.
* @nmaskbits: size of bitmap, in bits.
*
* Commas group hex digits into chunks. Each chunk defines exactly 32
* bits of the resultant bitmask. No chunk may specify a value larger
* than 32 bits (%-EOVERFLOW), and if a chunk specifies a smaller value
* then leading 0-bits are prepended. %-EINVAL is returned for illegal
* characters and for grouping errors such as "1,,5", ",44", "," and "".
* Leading and trailing whitespace accepted, but not embedded whitespace.
*/
int __bitmap_parse(const char *buf, unsigned int buflen,
int is_user, unsigned long *maskp,
int nmaskbits)
{
int c, old_c, totaldigits, ndigits, nchunks, nbits;
u32 chunk;
const char __user __force *ubuf = (const char __user __force *)buf;
bitmap_zero(maskp, nmaskbits);
nchunks = nbits = totaldigits = c = 0;
do {
chunk = 0;
ndigits = totaldigits;
/* Get the next chunk of the bitmap */
while (buflen) {
old_c = c;
if (is_user) {
if (__get_user(c, ubuf++))
return -EFAULT;
}
else
c = *buf++;
buflen--;
if (isspace(c))
continue;
/*
* If the last character was a space and the current
* character isn't '\0', we've got embedded whitespace.
* This is a no-no, so throw an error.
*/
if (totaldigits && c && isspace(old_c))
return -EINVAL;
/* A '\0' or a ',' signal the end of the chunk */
if (c == '\0' || c == ',')
break;
if (!isxdigit(c))
return -EINVAL;
/*
* Make sure there are at least 4 free bits in 'chunk'.
* If not, this hexdigit will overflow 'chunk', so
* throw an error.
*/
if (chunk & ~((1UL << (CHUNKSZ - 4)) - 1))
return -EOVERFLOW;
chunk = (chunk << 4) | hex_to_bin(c);
totaldigits++;
}
if (ndigits == totaldigits)
return -EINVAL;
if (nchunks == 0 && chunk == 0)
continue;
__bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits);
*maskp |= chunk;
nchunks++;
nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ;
if (nbits > nmaskbits)
return -EOVERFLOW;
} while (buflen && c == ',');
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrew Morton | 247 | 84.88% | 4 | 50.00% |
Reinette Chatre | 31 | 10.65% | 1 | 12.50% |
H Hartley Sweeten | 8 | 2.75% | 1 | 12.50% |
Pan Xinhui | 4 | 1.37% | 1 | 12.50% |
Andy Shevchenko | 1 | 0.34% | 1 | 12.50% |
Total | 291 | 100.00% | 8 | 100.00% |
EXPORT_SYMBOL(__bitmap_parse);
/**
* bitmap_parse_user - convert an ASCII hex string in a user buffer into a bitmap
*
* @ubuf: pointer to user buffer containing string.
* @ulen: buffer size in bytes. If string is smaller than this
* then it must be terminated with a \0.
* @maskp: pointer to bitmap array that will contain result.
* @nmaskbits: size of bitmap, in bits.
*
* Wrapper for __bitmap_parse(), providing it with user buffer.
*
* We cannot have this as an inline function in bitmap.h because it needs
* linux/uaccess.h to get the access_ok() declaration and this causes
* cyclic dependencies.
*/
int bitmap_parse_user(const char __user *ubuf,
unsigned int ulen, unsigned long *maskp,
int nmaskbits)
{
if (!access_ok(VERIFY_READ, ubuf, ulen))
return -EFAULT;
return __bitmap_parse((const char __force *)ubuf,
ulen, 1, maskp, nmaskbits);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Reinette Chatre | 58 | 98.31% | 1 | 50.00% |
H Hartley Sweeten | 1 | 1.69% | 1 | 50.00% |
Total | 59 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(bitmap_parse_user);
/**
* bitmap_print_to_pagebuf - convert bitmap to list or hex format ASCII string
* @list: indicates whether the bitmap must be list
* @buf: page aligned buffer into which string is placed
* @maskp: pointer to bitmap to convert
* @nmaskbits: size of bitmap, in bits
*
* Output format is a comma-separated list of decimal numbers and
* ranges if list is specified or hex digits grouped into comma-separated
* sets of 8 digits/set. Returns the number of characters written to buf.
*
* It is assumed that @buf is a pointer into a PAGE_SIZE area and that
* sufficient storage remains at @buf to accommodate the
* bitmap_print_to_pagebuf() output.
*/
int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp,
int nmaskbits)
{
ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
int n = 0;
if (len > 1)
n = list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) :
scnprintf(buf, len, "%*pb\n", nmaskbits, maskp);
return n;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Sudeep Holla | 75 | 92.59% | 2 | 66.67% |
Tejun Heo | 6 | 7.41% | 1 | 33.33% |
Total | 81 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(bitmap_print_to_pagebuf);
/**
* __bitmap_parselist - convert list format ASCII string to bitmap
* @buf: read nul-terminated user string from this buffer
* @buflen: buffer size in bytes. If string is smaller than this
* then it must be terminated with a \0.
* @is_user: location of buffer, 0 indicates kernel space
* @maskp: write resulting mask here
* @nmaskbits: number of bits in mask to be written
*
* Input format is a comma-separated list of decimal numbers and
* ranges. Consecutively set bits are shown as two hyphen-separated
* decimal numbers, the smallest and largest bit numbers set in
* the range.
* Optionally each range can be postfixed to denote that only parts of it
* should be set. The range will divided to groups of specific size.
* From each group will be used only defined amount of bits.
* Syntax: range:used_size/group_size
* Example: 0-1023:2/256 ==> 0,1,256,257,512,513,768,769
*
* Returns: 0 on success, -errno on invalid input strings. Error values:
*
* - ``-EINVAL``: second number in range smaller than first
* - ``-EINVAL``: invalid character in string
* - ``-ERANGE``: bit number specified too large for mask
*/
static int __bitmap_parselist(const char *buf, unsigned int buflen,
int is_user, unsigned long *maskp,
int nmaskbits)
{
unsigned int a, b, old_a, old_b;
unsigned int group_size, used_size;
int c, old_c, totaldigits, ndigits;
const char __user __force *ubuf = (const char __user __force *)buf;
int at_start, in_range, in_partial_range;
totaldigits = c = 0;
old_a = old_b = 0;
group_size = used_size = 0;
bitmap_zero(maskp, nmaskbits);
do {
at_start = 1;
in_range = 0;
in_partial_range = 0;
a = b = 0;
ndigits = totaldigits;
/* Get the next cpu# or a range of cpu#'s */
while (buflen) {
old_c = c;
if (is_user) {
if (__get_user(c, ubuf++))
return -EFAULT;
} else
c = *buf++;
buflen--;
if (isspace(c))
continue;
/* A '\0' or a ',' signal the end of a cpu# or range */
if (c == '\0' || c == ',')
break;
/*
* whitespaces between digits are not allowed,
* but it's ok if whitespaces are on head or tail.
* when old_c is whilespace,
* if totaldigits == ndigits, whitespace is on head.
* if whitespace is on tail, it should not run here.
* as c was ',' or '\0',
* the last code line has broken the current loop.
*/
if ((totaldigits != ndigits) && isspace(old_c))
return -EINVAL;
if (c == '/') {
used_size = a;
at_start = 1;
in_range = 0;
a = b = 0;
continue;
}
if (c == ':') {
old_a = a;
old_b = b;
at_start = 1;
in_range = 0;
in_partial_range = 1;
a = b = 0;
continue;
}
if (c == '-') {
if (at_start || in_range)
return -EINVAL;
b = 0;
in_range = 1;
at_start = 1;
continue;
}
if (!isdigit(c))
return -EINVAL;
b = b * 10 + (c - '0');
if (!in_range)
a = b;
at_start = 0;
totaldigits++;
}
if (ndigits == totaldigits)
continue;
if (in_partial_range) {
group_size = a;
a = old_a;
b = old_b;
old_a = old_b = 0;
}
/* if no digit is after '-', it's wrong*/
if (at_start && in_range)
return -EINVAL;
if (!(a <= b) || !(used_size <= group_size))
return -EINVAL;
if (b >= nmaskbits)
return -ERANGE;
while (a <= b) {
if (in_partial_range) {
static int pos_in_group = 1;
if (pos_in_group <= used_size)
set_bit(a, maskp);
if (a == b || ++pos_in_group > group_size)
pos_in_group = 1;
} else
set_bit(a, maskp);
a++;
}
} while (buflen && c == ',');
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Noam Camus | 163 | 34.03% | 1 | 14.29% |
Mike Travis | 149 | 31.11% | 1 | 14.29% |
Paul Jackson | 110 | 22.96% | 1 | 14.29% |
Pan Xinhui | 45 | 9.39% | 2 | 28.57% |
H Hartley Sweeten | 8 | 1.67% | 1 | 14.29% |
Chris Metcalf | 4 | 0.84% | 1 | 14.29% |
Total | 479 | 100.00% | 7 | 100.00% |
int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
{
char *nl = strchrnul(bp, '\n');
int len = nl - bp;
return __bitmap_parselist(bp, len, 0, maskp, nmaskbits);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Mike Travis | 40 | 80.00% | 1 | 33.33% |
Paul Jackson | 7 | 14.00% | 1 | 33.33% |
Rasmus Villemoes | 3 | 6.00% | 1 | 33.33% |
Total | 50 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(bitmap_parselist);
/**
* bitmap_parselist_user()
*
* @ubuf: pointer to user buffer containing string.
* @ulen: buffer size in bytes. If string is smaller than this
* then it must be terminated with a \0.
* @maskp: pointer to bitmap array that will contain result.
* @nmaskbits: size of bitmap, in bits.
*
* Wrapper for bitmap_parselist(), providing it with user buffer.
*
* We cannot have this as an inline function in bitmap.h because it needs
* linux/uaccess.h to get the access_ok() declaration and this causes
* cyclic dependencies.
*/
int bitmap_parselist_user(const char __user *ubuf,
unsigned int ulen, unsigned long *maskp,
int nmaskbits)
{
if (!access_ok(VERIFY_READ, ubuf, ulen))
return -EFAULT;
return __bitmap_parselist((const char __force *)ubuf,
ulen, 1, maskp, nmaskbits);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Mike Travis | 58 | 98.31% | 1 | 50.00% |
H Hartley Sweeten | 1 | 1.69% | 1 | 50.00% |
Total | 59 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(bitmap_parselist_user);
/**
* bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
* @buf: pointer to a bitmap
* @pos: a bit position in @buf (0 <= @pos < @nbits)
* @nbits: number of valid bit positions in @buf
*
* Map the bit at position @pos in @buf (of length @nbits) to the
* ordinal of which set bit it is. If it is not set or if @pos
* is not a valid bit position, map to -1.
*
* If for example, just bits 4 through 7 are set in @buf, then @pos
* values 4 through 7 will get mapped to 0 through 3, respectively,
* and other @pos values will get mapped to -1. When @pos value 7
* gets mapped to (returns) @ord value 3 in this example, that means
* that bit 7 is the 3rd (starting with 0th) set bit in @buf.
*
* The bit positions 0 through @bits are valid positions in @buf.
*/
static int bitmap_pos_to_ord(const unsigned long *buf, unsigned int pos, unsigned int nbits)
{
if (pos >= nbits || !test_bit(pos, buf))
return -1;
return __bitmap_weight(buf, pos);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Paul Jackson | 40 | 86.96% | 2 | 66.67% |
Rasmus Villemoes | 6 | 13.04% | 1 | 33.33% |
Total | 46 | 100.00% | 3 | 100.00% |
/**
* bitmap_ord_to_pos - find position of n-th set bit in bitmap
* @buf: pointer to bitmap
* @ord: ordinal bit position (n-th set bit, n >= 0)
* @nbits: number of valid bit positions in @buf
*
* Map the ordinal offset of bit @ord in @buf to its position in @buf.
* Value of @ord should be in range 0 <= @ord < weight(buf). If @ord
* >= weight(buf), returns @nbits.
*
* If for example, just bits 4 through 7 are set in @buf, then @ord
* values 0 through 3 will get mapped to 4 through 7, respectively,
* and all other @ord values returns @nbits. When @ord value 3
* gets mapped to (returns) @pos value 7 in this example, that means
* that the 3rd set bit (starting with 0th) is at position 7 in @buf.
*
* The bit positions 0 through @nbits-1 are valid positions in @buf.
*/
unsigned int bitmap_ord_to_pos(const unsigned long *buf, unsigned int ord, unsigned int nbits)
{
unsigned int pos;
for (pos = find_first_bit(buf, nbits);
pos < nbits && ord;
pos = find_next_bit(buf, nbits, pos + 1))
ord--;
return pos;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
|