diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Kconfig.debug | 9 | ||||
| -rw-r--r-- | lib/crc32.c | 9 | ||||
| -rw-r--r-- | lib/decompress.c | 9 | ||||
| -rw-r--r-- | lib/gcd.c | 3 | ||||
| -rw-r--r-- | lib/gen_crc32table.c | 6 | ||||
| -rw-r--r-- | lib/genalloc.c | 88 | ||||
| -rw-r--r-- | lib/idr.c | 32 | ||||
| -rw-r--r-- | lib/parser.c | 10 | ||||
| -rw-r--r-- | lib/plist.c | 4 | ||||
| -rw-r--r-- | lib/scatterlist.c | 16 | ||||
| -rw-r--r-- | lib/spinlock_debug.c | 32 | ||||
| -rw-r--r-- | lib/vsprintf.c | 139 |
12 files changed, 226 insertions, 131 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 35c4565ee8fa..7fba3a98967f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -196,12 +196,13 @@ config LOCKUP_DETECTOR | |||
| 196 | thresholds can be controlled through the sysctl watchdog_thresh. | 196 | thresholds can be controlled through the sysctl watchdog_thresh. |
| 197 | 197 | ||
| 198 | config HARDLOCKUP_DETECTOR | 198 | config HARDLOCKUP_DETECTOR |
| 199 | def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI && \ | 199 | def_bool y |
| 200 | !HAVE_NMI_WATCHDOG | 200 | depends on LOCKUP_DETECTOR && !HAVE_NMI_WATCHDOG |
| 201 | depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI | ||
| 201 | 202 | ||
| 202 | config BOOTPARAM_HARDLOCKUP_PANIC | 203 | config BOOTPARAM_HARDLOCKUP_PANIC |
| 203 | bool "Panic (Reboot) On Hard Lockups" | 204 | bool "Panic (Reboot) On Hard Lockups" |
| 204 | depends on LOCKUP_DETECTOR | 205 | depends on HARDLOCKUP_DETECTOR |
| 205 | help | 206 | help |
| 206 | Say Y here to enable the kernel to panic on "hard lockups", | 207 | Say Y here to enable the kernel to panic on "hard lockups", |
| 207 | which are bugs that cause the kernel to loop in kernel | 208 | which are bugs that cause the kernel to loop in kernel |
| @@ -212,7 +213,7 @@ config BOOTPARAM_HARDLOCKUP_PANIC | |||
| 212 | 213 | ||
| 213 | config BOOTPARAM_HARDLOCKUP_PANIC_VALUE | 214 | config BOOTPARAM_HARDLOCKUP_PANIC_VALUE |
| 214 | int | 215 | int |
| 215 | depends on LOCKUP_DETECTOR | 216 | depends on HARDLOCKUP_DETECTOR |
| 216 | range 0 1 | 217 | range 0 1 |
| 217 | default 0 if !BOOTPARAM_HARDLOCKUP_PANIC | 218 | default 0 if !BOOTPARAM_HARDLOCKUP_PANIC |
| 218 | default 1 if BOOTPARAM_HARDLOCKUP_PANIC | 219 | default 1 if BOOTPARAM_HARDLOCKUP_PANIC |
diff --git a/lib/crc32.c b/lib/crc32.c index 61774b8db4de..072fbd8234d5 100644 --- a/lib/crc32.c +++ b/lib/crc32.c | |||
| @@ -188,11 +188,13 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) | |||
| 188 | #else | 188 | #else |
| 189 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | 189 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) |
| 190 | { | 190 | { |
| 191 | return crc32_le_generic(crc, p, len, crc32table_le, CRCPOLY_LE); | 191 | return crc32_le_generic(crc, p, len, |
| 192 | (const u32 (*)[256])crc32table_le, CRCPOLY_LE); | ||
| 192 | } | 193 | } |
| 193 | u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) | 194 | u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) |
| 194 | { | 195 | { |
| 195 | return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE); | 196 | return crc32_le_generic(crc, p, len, |
| 197 | (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE); | ||
| 196 | } | 198 | } |
| 197 | #endif | 199 | #endif |
| 198 | EXPORT_SYMBOL(crc32_le); | 200 | EXPORT_SYMBOL(crc32_le); |
| @@ -253,7 +255,8 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | |||
| 253 | #else | 255 | #else |
| 254 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | 256 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) |
| 255 | { | 257 | { |
| 256 | return crc32_be_generic(crc, p, len, crc32table_be, CRCPOLY_BE); | 258 | return crc32_be_generic(crc, p, len, |
| 259 | (const u32 (*)[256])crc32table_be, CRCPOLY_BE); | ||
| 257 | } | 260 | } |
| 258 | #endif | 261 | #endif |
| 259 | EXPORT_SYMBOL(crc32_be); | 262 | EXPORT_SYMBOL(crc32_be); |
diff --git a/lib/decompress.c b/lib/decompress.c index 3d766b7f60ab..31a804277282 100644 --- a/lib/decompress.c +++ b/lib/decompress.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
| 17 | #include <linux/init.h> | ||
| 17 | 18 | ||
| 18 | #ifndef CONFIG_DECOMPRESS_GZIP | 19 | #ifndef CONFIG_DECOMPRESS_GZIP |
| 19 | # define gunzip NULL | 20 | # define gunzip NULL |
| @@ -31,11 +32,13 @@ | |||
| 31 | # define unlzo NULL | 32 | # define unlzo NULL |
| 32 | #endif | 33 | #endif |
| 33 | 34 | ||
| 34 | static const struct compress_format { | 35 | struct compress_format { |
| 35 | unsigned char magic[2]; | 36 | unsigned char magic[2]; |
| 36 | const char *name; | 37 | const char *name; |
| 37 | decompress_fn decompressor; | 38 | decompress_fn decompressor; |
| 38 | } compressed_formats[] = { | 39 | }; |
| 40 | |||
| 41 | static const struct compress_format compressed_formats[] __initdata = { | ||
| 39 | { {037, 0213}, "gzip", gunzip }, | 42 | { {037, 0213}, "gzip", gunzip }, |
| 40 | { {037, 0236}, "gzip", gunzip }, | 43 | { {037, 0236}, "gzip", gunzip }, |
| 41 | { {0x42, 0x5a}, "bzip2", bunzip2 }, | 44 | { {0x42, 0x5a}, "bzip2", bunzip2 }, |
| @@ -45,7 +48,7 @@ static const struct compress_format { | |||
| 45 | { {0, 0}, NULL, NULL } | 48 | { {0, 0}, NULL, NULL } |
| 46 | }; | 49 | }; |
| 47 | 50 | ||
| 48 | decompress_fn decompress_method(const unsigned char *inbuf, int len, | 51 | decompress_fn __init decompress_method(const unsigned char *inbuf, int len, |
| 49 | const char **name) | 52 | const char **name) |
| 50 | { | 53 | { |
| 51 | const struct compress_format *cf; | 54 | const struct compress_format *cf; |
| @@ -9,6 +9,9 @@ unsigned long gcd(unsigned long a, unsigned long b) | |||
| 9 | 9 | ||
| 10 | if (a < b) | 10 | if (a < b) |
| 11 | swap(a, b); | 11 | swap(a, b); |
| 12 | |||
| 13 | if (!b) | ||
| 14 | return a; | ||
| 12 | while ((r = a % b) != 0) { | 15 | while ((r = a % b) != 0) { |
| 13 | a = b; | 16 | a = b; |
| 14 | b = r; | 17 | b = r; |
diff --git a/lib/gen_crc32table.c b/lib/gen_crc32table.c index 8f8d5439e2d9..71fcfcd96410 100644 --- a/lib/gen_crc32table.c +++ b/lib/gen_crc32table.c | |||
| @@ -109,7 +109,7 @@ int main(int argc, char** argv) | |||
| 109 | 109 | ||
| 110 | if (CRC_LE_BITS > 1) { | 110 | if (CRC_LE_BITS > 1) { |
| 111 | crc32init_le(); | 111 | crc32init_le(); |
| 112 | printf("static const u32 __cacheline_aligned " | 112 | printf("static u32 __cacheline_aligned " |
| 113 | "crc32table_le[%d][%d] = {", | 113 | "crc32table_le[%d][%d] = {", |
| 114 | LE_TABLE_ROWS, LE_TABLE_SIZE); | 114 | LE_TABLE_ROWS, LE_TABLE_SIZE); |
| 115 | output_table(crc32table_le, LE_TABLE_ROWS, | 115 | output_table(crc32table_le, LE_TABLE_ROWS, |
| @@ -119,7 +119,7 @@ int main(int argc, char** argv) | |||
| 119 | 119 | ||
| 120 | if (CRC_BE_BITS > 1) { | 120 | if (CRC_BE_BITS > 1) { |
| 121 | crc32init_be(); | 121 | crc32init_be(); |
| 122 | printf("static const u32 __cacheline_aligned " | 122 | printf("static u32 __cacheline_aligned " |
| 123 | "crc32table_be[%d][%d] = {", | 123 | "crc32table_be[%d][%d] = {", |
| 124 | BE_TABLE_ROWS, BE_TABLE_SIZE); | 124 | BE_TABLE_ROWS, BE_TABLE_SIZE); |
| 125 | output_table(crc32table_be, LE_TABLE_ROWS, | 125 | output_table(crc32table_be, LE_TABLE_ROWS, |
| @@ -128,7 +128,7 @@ int main(int argc, char** argv) | |||
| 128 | } | 128 | } |
| 129 | if (CRC_LE_BITS > 1) { | 129 | if (CRC_LE_BITS > 1) { |
| 130 | crc32cinit_le(); | 130 | crc32cinit_le(); |
| 131 | printf("static const u32 __cacheline_aligned " | 131 | printf("static u32 __cacheline_aligned " |
| 132 | "crc32ctable_le[%d][%d] = {", | 132 | "crc32ctable_le[%d][%d] = {", |
| 133 | LE_TABLE_ROWS, LE_TABLE_SIZE); | 133 | LE_TABLE_ROWS, LE_TABLE_SIZE); |
| 134 | output_table(crc32ctable_le, LE_TABLE_ROWS, | 134 | output_table(crc32ctable_le, LE_TABLE_ROWS, |
diff --git a/lib/genalloc.c b/lib/genalloc.c index 6bc04aab6ec7..ca208a92628c 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
| @@ -152,6 +152,8 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) | |||
| 152 | spin_lock_init(&pool->lock); | 152 | spin_lock_init(&pool->lock); |
| 153 | INIT_LIST_HEAD(&pool->chunks); | 153 | INIT_LIST_HEAD(&pool->chunks); |
| 154 | pool->min_alloc_order = min_alloc_order; | 154 | pool->min_alloc_order = min_alloc_order; |
| 155 | pool->algo = gen_pool_first_fit; | ||
| 156 | pool->data = NULL; | ||
| 155 | } | 157 | } |
| 156 | return pool; | 158 | return pool; |
| 157 | } | 159 | } |
| @@ -255,8 +257,9 @@ EXPORT_SYMBOL(gen_pool_destroy); | |||
| 255 | * @size: number of bytes to allocate from the pool | 257 | * @size: number of bytes to allocate from the pool |
| 256 | * | 258 | * |
| 257 | * Allocate the requested number of bytes from the specified pool. | 259 | * Allocate the requested number of bytes from the specified pool. |
| 258 | * Uses a first-fit algorithm. Can not be used in NMI handler on | 260 | * Uses the pool allocation function (with first-fit algorithm by default). |
| 259 | * architectures without NMI-safe cmpxchg implementation. | 261 | * Can not be used in NMI handler on architectures without |
| 262 | * NMI-safe cmpxchg implementation. | ||
| 260 | */ | 263 | */ |
| 261 | unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) | 264 | unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) |
| 262 | { | 265 | { |
| @@ -280,8 +283,8 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) | |||
| 280 | 283 | ||
| 281 | end_bit = (chunk->end_addr - chunk->start_addr) >> order; | 284 | end_bit = (chunk->end_addr - chunk->start_addr) >> order; |
| 282 | retry: | 285 | retry: |
| 283 | start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, | 286 | start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits, |
| 284 | start_bit, nbits, 0); | 287 | pool->data); |
| 285 | if (start_bit >= end_bit) | 288 | if (start_bit >= end_bit) |
| 286 | continue; | 289 | continue; |
| 287 | remain = bitmap_set_ll(chunk->bits, start_bit, nbits); | 290 | remain = bitmap_set_ll(chunk->bits, start_bit, nbits); |
| @@ -400,3 +403,80 @@ size_t gen_pool_size(struct gen_pool *pool) | |||
| 400 | return size; | 403 | return size; |
| 401 | } | 404 | } |
| 402 | EXPORT_SYMBOL_GPL(gen_pool_size); | 405 | EXPORT_SYMBOL_GPL(gen_pool_size); |
| 406 | |||
| 407 | /** | ||
| 408 | * gen_pool_set_algo - set the allocation algorithm | ||
| 409 | * @pool: pool to change allocation algorithm | ||
| 410 | * @algo: custom algorithm function | ||
| 411 | * @data: additional data used by @algo | ||
| 412 | * | ||
| 413 | * Call @algo for each memory allocation in the pool. | ||
| 414 | * If @algo is NULL use gen_pool_first_fit as default | ||
| 415 | * memory allocation function. | ||
| 416 | */ | ||
| 417 | void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, void *data) | ||
| 418 | { | ||
| 419 | rcu_read_lock(); | ||
| 420 | |||
| 421 | pool->algo = algo; | ||
| 422 | if (!pool->algo) | ||
| 423 | pool->algo = gen_pool_first_fit; | ||
| 424 | |||
| 425 | pool->data = data; | ||
| 426 | |||
| 427 | rcu_read_unlock(); | ||
| 428 | } | ||
| 429 | EXPORT_SYMBOL(gen_pool_set_algo); | ||
| 430 | |||
| 431 | /** | ||
| 432 | * gen_pool_first_fit - find the first available region | ||
| 433 | * of memory matching the size requirement (no alignment constraint) | ||
| 434 | * @map: The address to base the search on | ||
| 435 | * @size: The bitmap size in bits | ||
| 436 | * @start: The bitnumber to start searching at | ||
| 437 | * @nr: The number of zeroed bits we're looking for | ||
| 438 | * @data: additional data - unused | ||
| 439 | */ | ||
| 440 | unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, | ||
| 441 | unsigned long start, unsigned int nr, void *data) | ||
| 442 | { | ||
| 443 | return bitmap_find_next_zero_area(map, size, start, nr, 0); | ||
| 444 | } | ||
| 445 | EXPORT_SYMBOL(gen_pool_first_fit); | ||
| 446 | |||
| 447 | /** | ||
| 448 | * gen_pool_best_fit - find the best fitting region of memory | ||
| 449 | * macthing the size requirement (no alignment constraint) | ||
| 450 | * @map: The address to base the search on | ||
| 451 | * @size: The bitmap size in bits | ||
| 452 | * @start: The bitnumber to start searching at | ||
| 453 | * @nr: The number of zeroed bits we're looking for | ||
| 454 | * @data: additional data - unused | ||
| 455 | * | ||
| 456 | * Iterate over the bitmap to find the smallest free region | ||
| 457 | * which we can allocate the memory. | ||
| 458 | */ | ||
| 459 | unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, | ||
| 460 | unsigned long start, unsigned int nr, void *data) | ||
| 461 | { | ||
| 462 | unsigned long start_bit = size; | ||
| 463 | unsigned long len = size + 1; | ||
| 464 | unsigned long index; | ||
| 465 | |||
| 466 | index = bitmap_find_next_zero_area(map, size, start, nr, 0); | ||
| 467 | |||
| 468 | while (index < size) { | ||
| 469 | int next_bit = find_next_bit(map, size, index + nr); | ||
| 470 | if ((next_bit - index) < len) { | ||
| 471 | len = next_bit - index; | ||
| 472 | start_bit = index; | ||
| 473 | if (len == nr) | ||
| 474 | return start_bit; | ||
| 475 | } | ||
| 476 | index = bitmap_find_next_zero_area(map, size, | ||
| 477 | next_bit + 1, nr, 0); | ||
| 478 | } | ||
| 479 | |||
| 480 | return start_bit; | ||
| 481 | } | ||
| 482 | EXPORT_SYMBOL(gen_pool_best_fit); | ||
| @@ -20,7 +20,7 @@ | |||
| 20 | * that id to this code and it returns your pointer. | 20 | * that id to this code and it returns your pointer. |
| 21 | 21 | ||
| 22 | * You can release ids at any time. When all ids are released, most of | 22 | * You can release ids at any time. When all ids are released, most of |
| 23 | * the memory is returned (we keep IDR_FREE_MAX) in a local pool so we | 23 | * the memory is returned (we keep MAX_IDR_FREE) in a local pool so we |
| 24 | * don't need to go to the memory "store" during an id allocate, just | 24 | * don't need to go to the memory "store" during an id allocate, just |
| 25 | * so you don't need to be too concerned about locking and conflicts | 25 | * so you don't need to be too concerned about locking and conflicts |
| 26 | * with the slab allocator. | 26 | * with the slab allocator. |
| @@ -122,7 +122,7 @@ static void idr_mark_full(struct idr_layer **pa, int id) | |||
| 122 | */ | 122 | */ |
| 123 | int idr_pre_get(struct idr *idp, gfp_t gfp_mask) | 123 | int idr_pre_get(struct idr *idp, gfp_t gfp_mask) |
| 124 | { | 124 | { |
| 125 | while (idp->id_free_cnt < IDR_FREE_MAX) { | 125 | while (idp->id_free_cnt < MAX_IDR_FREE) { |
| 126 | struct idr_layer *new; | 126 | struct idr_layer *new; |
| 127 | new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); | 127 | new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); |
| 128 | if (new == NULL) | 128 | if (new == NULL) |
| @@ -179,7 +179,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
| 179 | sh = IDR_BITS*l; | 179 | sh = IDR_BITS*l; |
| 180 | id = ((id >> sh) ^ n ^ m) << sh; | 180 | id = ((id >> sh) ^ n ^ m) << sh; |
| 181 | } | 181 | } |
| 182 | if ((id >= MAX_ID_BIT) || (id < 0)) | 182 | if ((id >= MAX_IDR_BIT) || (id < 0)) |
| 183 | return IDR_NOMORE_SPACE; | 183 | return IDR_NOMORE_SPACE; |
| 184 | if (l == 0) | 184 | if (l == 0) |
| 185 | break; | 185 | break; |
| @@ -223,7 +223,7 @@ build_up: | |||
| 223 | * Add a new layer to the top of the tree if the requested | 223 | * Add a new layer to the top of the tree if the requested |
| 224 | * id is larger than the currently allocated space. | 224 | * id is larger than the currently allocated space. |
| 225 | */ | 225 | */ |
| 226 | while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { | 226 | while ((layers < (MAX_IDR_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { |
| 227 | layers++; | 227 | layers++; |
| 228 | if (!p->count) { | 228 | if (!p->count) { |
| 229 | /* special case: if the tree is currently empty, | 229 | /* special case: if the tree is currently empty, |
| @@ -265,7 +265,7 @@ build_up: | |||
| 265 | 265 | ||
| 266 | static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) | 266 | static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) |
| 267 | { | 267 | { |
| 268 | struct idr_layer *pa[MAX_LEVEL]; | 268 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
| 269 | int id; | 269 | int id; |
| 270 | 270 | ||
| 271 | id = idr_get_empty_slot(idp, starting_id, pa); | 271 | id = idr_get_empty_slot(idp, starting_id, pa); |
| @@ -357,7 +357,7 @@ static void idr_remove_warning(int id) | |||
| 357 | static void sub_remove(struct idr *idp, int shift, int id) | 357 | static void sub_remove(struct idr *idp, int shift, int id) |
| 358 | { | 358 | { |
| 359 | struct idr_layer *p = idp->top; | 359 | struct idr_layer *p = idp->top; |
| 360 | struct idr_layer **pa[MAX_LEVEL]; | 360 | struct idr_layer **pa[MAX_IDR_LEVEL]; |
| 361 | struct idr_layer ***paa = &pa[0]; | 361 | struct idr_layer ***paa = &pa[0]; |
| 362 | struct idr_layer *to_free; | 362 | struct idr_layer *to_free; |
| 363 | int n; | 363 | int n; |
| @@ -402,7 +402,7 @@ void idr_remove(struct idr *idp, int id) | |||
| 402 | struct idr_layer *to_free; | 402 | struct idr_layer *to_free; |
| 403 | 403 | ||
| 404 | /* Mask off upper bits we don't use for the search. */ | 404 | /* Mask off upper bits we don't use for the search. */ |
| 405 | id &= MAX_ID_MASK; | 405 | id &= MAX_IDR_MASK; |
| 406 | 406 | ||
| 407 | sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); | 407 | sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); |
| 408 | if (idp->top && idp->top->count == 1 && (idp->layers > 1) && | 408 | if (idp->top && idp->top->count == 1 && (idp->layers > 1) && |
| @@ -420,7 +420,7 @@ void idr_remove(struct idr *idp, int id) | |||
| 420 | to_free->bitmap = to_free->count = 0; | 420 | to_free->bitmap = to_free->count = 0; |
| 421 | free_layer(to_free); | 421 | free_layer(to_free); |
| 422 | } | 422 | } |
| 423 | while (idp->id_free_cnt >= IDR_FREE_MAX) { | 423 | while (idp->id_free_cnt >= MAX_IDR_FREE) { |
| 424 | p = get_from_free_list(idp); | 424 | p = get_from_free_list(idp); |
| 425 | /* | 425 | /* |
| 426 | * Note: we don't call the rcu callback here, since the only | 426 | * Note: we don't call the rcu callback here, since the only |
| @@ -451,7 +451,7 @@ void idr_remove_all(struct idr *idp) | |||
| 451 | int n, id, max; | 451 | int n, id, max; |
| 452 | int bt_mask; | 452 | int bt_mask; |
| 453 | struct idr_layer *p; | 453 | struct idr_layer *p; |
| 454 | struct idr_layer *pa[MAX_LEVEL]; | 454 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
| 455 | struct idr_layer **paa = &pa[0]; | 455 | struct idr_layer **paa = &pa[0]; |
| 456 | 456 | ||
| 457 | n = idp->layers * IDR_BITS; | 457 | n = idp->layers * IDR_BITS; |
| @@ -517,7 +517,7 @@ void *idr_find(struct idr *idp, int id) | |||
| 517 | n = (p->layer+1) * IDR_BITS; | 517 | n = (p->layer+1) * IDR_BITS; |
| 518 | 518 | ||
| 519 | /* Mask off upper bits we don't use for the search. */ | 519 | /* Mask off upper bits we don't use for the search. */ |
| 520 | id &= MAX_ID_MASK; | 520 | id &= MAX_IDR_MASK; |
| 521 | 521 | ||
| 522 | if (id >= (1 << n)) | 522 | if (id >= (1 << n)) |
| 523 | return NULL; | 523 | return NULL; |
| @@ -555,7 +555,7 @@ int idr_for_each(struct idr *idp, | |||
| 555 | { | 555 | { |
| 556 | int n, id, max, error = 0; | 556 | int n, id, max, error = 0; |
| 557 | struct idr_layer *p; | 557 | struct idr_layer *p; |
| 558 | struct idr_layer *pa[MAX_LEVEL]; | 558 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
| 559 | struct idr_layer **paa = &pa[0]; | 559 | struct idr_layer **paa = &pa[0]; |
| 560 | 560 | ||
| 561 | n = idp->layers * IDR_BITS; | 561 | n = idp->layers * IDR_BITS; |
| @@ -601,7 +601,7 @@ EXPORT_SYMBOL(idr_for_each); | |||
| 601 | */ | 601 | */ |
| 602 | void *idr_get_next(struct idr *idp, int *nextidp) | 602 | void *idr_get_next(struct idr *idp, int *nextidp) |
| 603 | { | 603 | { |
| 604 | struct idr_layer *p, *pa[MAX_LEVEL]; | 604 | struct idr_layer *p, *pa[MAX_IDR_LEVEL]; |
| 605 | struct idr_layer **paa = &pa[0]; | 605 | struct idr_layer **paa = &pa[0]; |
| 606 | int id = *nextidp; | 606 | int id = *nextidp; |
| 607 | int n, max; | 607 | int n, max; |
| @@ -659,7 +659,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) | |||
| 659 | 659 | ||
| 660 | n = (p->layer+1) * IDR_BITS; | 660 | n = (p->layer+1) * IDR_BITS; |
| 661 | 661 | ||
| 662 | id &= MAX_ID_MASK; | 662 | id &= MAX_IDR_MASK; |
| 663 | 663 | ||
| 664 | if (id >= (1 << n)) | 664 | if (id >= (1 << n)) |
| 665 | return ERR_PTR(-EINVAL); | 665 | return ERR_PTR(-EINVAL); |
| @@ -780,7 +780,7 @@ EXPORT_SYMBOL(ida_pre_get); | |||
| 780 | */ | 780 | */ |
| 781 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | 781 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) |
| 782 | { | 782 | { |
| 783 | struct idr_layer *pa[MAX_LEVEL]; | 783 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
| 784 | struct ida_bitmap *bitmap; | 784 | struct ida_bitmap *bitmap; |
| 785 | unsigned long flags; | 785 | unsigned long flags; |
| 786 | int idr_id = starting_id / IDA_BITMAP_BITS; | 786 | int idr_id = starting_id / IDA_BITMAP_BITS; |
| @@ -793,7 +793,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | |||
| 793 | if (t < 0) | 793 | if (t < 0) |
| 794 | return _idr_rc_to_errno(t); | 794 | return _idr_rc_to_errno(t); |
| 795 | 795 | ||
| 796 | if (t * IDA_BITMAP_BITS >= MAX_ID_BIT) | 796 | if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT) |
| 797 | return -ENOSPC; | 797 | return -ENOSPC; |
| 798 | 798 | ||
| 799 | if (t != idr_id) | 799 | if (t != idr_id) |
| @@ -827,7 +827,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | |||
| 827 | } | 827 | } |
| 828 | 828 | ||
| 829 | id = idr_id * IDA_BITMAP_BITS + t; | 829 | id = idr_id * IDA_BITMAP_BITS + t; |
| 830 | if (id >= MAX_ID_BIT) | 830 | if (id >= MAX_IDR_BIT) |
| 831 | return -ENOSPC; | 831 | return -ENOSPC; |
| 832 | 832 | ||
| 833 | __set_bit(t, bitmap->bitmap); | 833 | __set_bit(t, bitmap->bitmap); |
diff --git a/lib/parser.c b/lib/parser.c index c43410084838..52cfa69f73df 100644 --- a/lib/parser.c +++ b/lib/parser.c | |||
| @@ -122,13 +122,14 @@ int match_token(char *s, const match_table_t table, substring_t args[]) | |||
| 122 | * | 122 | * |
| 123 | * Description: Given a &substring_t and a base, attempts to parse the substring | 123 | * Description: Given a &substring_t and a base, attempts to parse the substring |
| 124 | * as a number in that base. On success, sets @result to the integer represented | 124 | * as a number in that base. On success, sets @result to the integer represented |
| 125 | * by the string and returns 0. Returns either -ENOMEM or -EINVAL on failure. | 125 | * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. |
| 126 | */ | 126 | */ |
| 127 | static int match_number(substring_t *s, int *result, int base) | 127 | static int match_number(substring_t *s, int *result, int base) |
| 128 | { | 128 | { |
| 129 | char *endp; | 129 | char *endp; |
| 130 | char *buf; | 130 | char *buf; |
| 131 | int ret; | 131 | int ret; |
| 132 | long val; | ||
| 132 | size_t len = s->to - s->from; | 133 | size_t len = s->to - s->from; |
| 133 | 134 | ||
| 134 | buf = kmalloc(len + 1, GFP_KERNEL); | 135 | buf = kmalloc(len + 1, GFP_KERNEL); |
| @@ -136,10 +137,15 @@ static int match_number(substring_t *s, int *result, int base) | |||
| 136 | return -ENOMEM; | 137 | return -ENOMEM; |
| 137 | memcpy(buf, s->from, len); | 138 | memcpy(buf, s->from, len); |
| 138 | buf[len] = '\0'; | 139 | buf[len] = '\0'; |
| 139 | *result = simple_strtol(buf, &endp, base); | 140 | |
| 140 | ret = 0; | 141 | ret = 0; |
| 142 | val = simple_strtol(buf, &endp, base); | ||
| 141 | if (endp == buf) | 143 | if (endp == buf) |
| 142 | ret = -EINVAL; | 144 | ret = -EINVAL; |
| 145 | else if (val < (long)INT_MIN || val > (long)INT_MAX) | ||
| 146 | ret = -ERANGE; | ||
| 147 | else | ||
| 148 | *result = (int) val; | ||
| 143 | kfree(buf); | 149 | kfree(buf); |
| 144 | return ret; | 150 | return ret; |
| 145 | } | 151 | } |
diff --git a/lib/plist.c b/lib/plist.c index 6ab0e521c48b..1ebc95f7a46f 100644 --- a/lib/plist.c +++ b/lib/plist.c | |||
| @@ -175,7 +175,7 @@ static int __init plist_test(void) | |||
| 175 | int nr_expect = 0, i, loop; | 175 | int nr_expect = 0, i, loop; |
| 176 | unsigned int r = local_clock(); | 176 | unsigned int r = local_clock(); |
| 177 | 177 | ||
| 178 | printk(KERN_INFO "start plist test\n"); | 178 | pr_debug("start plist test\n"); |
| 179 | plist_head_init(&test_head); | 179 | plist_head_init(&test_head); |
| 180 | for (i = 0; i < ARRAY_SIZE(test_node); i++) | 180 | for (i = 0; i < ARRAY_SIZE(test_node); i++) |
| 181 | plist_node_init(test_node + i, 0); | 181 | plist_node_init(test_node + i, 0); |
| @@ -203,7 +203,7 @@ static int __init plist_test(void) | |||
| 203 | plist_test_check(nr_expect); | 203 | plist_test_check(nr_expect); |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | printk(KERN_INFO "end plist test\n"); | 206 | pr_debug("end plist test\n"); |
| 207 | return 0; | 207 | return 0; |
| 208 | } | 208 | } |
| 209 | 209 | ||
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index fadae774a20c..e76d85cf3175 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
| @@ -404,14 +404,13 @@ EXPORT_SYMBOL(sg_miter_start); | |||
| 404 | * @miter: sg mapping iter to proceed | 404 | * @miter: sg mapping iter to proceed |
| 405 | * | 405 | * |
| 406 | * Description: | 406 | * Description: |
| 407 | * Proceeds @miter@ to the next mapping. @miter@ should have been | 407 | * Proceeds @miter to the next mapping. @miter should have been started |
| 408 | * started using sg_miter_start(). On successful return, | 408 | * using sg_miter_start(). On successful return, @miter->page, |
| 409 | * @miter@->page, @miter@->addr and @miter@->length point to the | 409 | * @miter->addr and @miter->length point to the current mapping. |
| 410 | * current mapping. | ||
| 411 | * | 410 | * |
| 412 | * Context: | 411 | * Context: |
| 413 | * IRQ disabled if SG_MITER_ATOMIC. IRQ must stay disabled till | 412 | * Preemption disabled if SG_MITER_ATOMIC. Preemption must stay disabled |
| 414 | * @miter@ is stopped. May sleep if !SG_MITER_ATOMIC. | 413 | * till @miter is stopped. May sleep if !SG_MITER_ATOMIC. |
| 415 | * | 414 | * |
| 416 | * Returns: | 415 | * Returns: |
| 417 | * true if @miter contains the next mapping. false if end of sg | 416 | * true if @miter contains the next mapping. false if end of sg |
| @@ -465,7 +464,8 @@ EXPORT_SYMBOL(sg_miter_next); | |||
| 465 | * resources (kmap) need to be released during iteration. | 464 | * resources (kmap) need to be released during iteration. |
| 466 | * | 465 | * |
| 467 | * Context: | 466 | * Context: |
| 468 | * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise. | 467 | * Preemption disabled if the SG_MITER_ATOMIC is set. Don't care |
| 468 | * otherwise. | ||
| 469 | */ | 469 | */ |
| 470 | void sg_miter_stop(struct sg_mapping_iter *miter) | 470 | void sg_miter_stop(struct sg_mapping_iter *miter) |
| 471 | { | 471 | { |
| @@ -479,7 +479,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter) | |||
| 479 | flush_kernel_dcache_page(miter->page); | 479 | flush_kernel_dcache_page(miter->page); |
| 480 | 480 | ||
| 481 | if (miter->__flags & SG_MITER_ATOMIC) { | 481 | if (miter->__flags & SG_MITER_ATOMIC) { |
| 482 | WARN_ON(!irqs_disabled()); | 482 | WARN_ON_ONCE(preemptible()); |
| 483 | kunmap_atomic(miter->addr); | 483 | kunmap_atomic(miter->addr); |
| 484 | } else | 484 | } else |
| 485 | kunmap(miter->page); | 485 | kunmap(miter->page); |
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index eb10578ae055..0374a596cffa 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c | |||
| @@ -107,23 +107,27 @@ static void __spin_lock_debug(raw_spinlock_t *lock) | |||
| 107 | { | 107 | { |
| 108 | u64 i; | 108 | u64 i; |
| 109 | u64 loops = loops_per_jiffy * HZ; | 109 | u64 loops = loops_per_jiffy * HZ; |
| 110 | int print_once = 1; | ||
| 111 | 110 | ||
| 112 | for (;;) { | 111 | for (i = 0; i < loops; i++) { |
| 113 | for (i = 0; i < loops; i++) { | 112 | if (arch_spin_trylock(&lock->raw_lock)) |
| 114 | if (arch_spin_trylock(&lock->raw_lock)) | 113 | return; |
| 115 | return; | 114 | __delay(1); |
| 116 | __delay(1); | 115 | } |
| 117 | } | 116 | /* lockup suspected: */ |
| 118 | /* lockup suspected: */ | 117 | spin_dump(lock, "lockup suspected"); |
| 119 | if (print_once) { | ||
| 120 | print_once = 0; | ||
| 121 | spin_dump(lock, "lockup suspected"); | ||
| 122 | #ifdef CONFIG_SMP | 118 | #ifdef CONFIG_SMP |
| 123 | trigger_all_cpu_backtrace(); | 119 | trigger_all_cpu_backtrace(); |
| 124 | #endif | 120 | #endif |
| 125 | } | 121 | |
| 126 | } | 122 | /* |
| 123 | * The trylock above was causing a livelock. Give the lower level arch | ||
| 124 | * specific lock code a chance to acquire the lock. We have already | ||
| 125 | * printed a warning/backtrace at this point. The non-debug arch | ||
| 126 | * specific code might actually succeed in acquiring the lock. If it is | ||
| 127 | * not successful, the end-result is the same - there is no forward | ||
| 128 | * progress. | ||
| 129 | */ | ||
| 130 | arch_spin_lock(&lock->raw_lock); | ||
| 127 | } | 131 | } |
| 128 | 132 | ||
| 129 | void do_raw_spin_lock(raw_spinlock_t *lock) | 133 | void do_raw_spin_lock(raw_spinlock_t *lock) |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 0e337541f005..39c99fea7c03 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -174,35 +174,25 @@ char *put_dec_trunc8(char *buf, unsigned r) | |||
| 174 | unsigned q; | 174 | unsigned q; |
| 175 | 175 | ||
| 176 | /* Copy of previous function's body with added early returns */ | 176 | /* Copy of previous function's body with added early returns */ |
| 177 | q = (r * (uint64_t)0x1999999a) >> 32; | 177 | while (r >= 10000) { |
| 178 | *buf++ = (r - 10 * q) + '0'; /* 2 */ | 178 | q = r + '0'; |
| 179 | if (q == 0) | 179 | r = (r * (uint64_t)0x1999999a) >> 32; |
| 180 | return buf; | 180 | *buf++ = q - 10*r; |
| 181 | r = (q * (uint64_t)0x1999999a) >> 32; | 181 | } |
| 182 | *buf++ = (q - 10 * r) + '0'; /* 3 */ | 182 | |
| 183 | if (r == 0) | 183 | q = (r * 0x199a) >> 16; /* r <= 9999 */ |
| 184 | return buf; | 184 | *buf++ = (r - 10 * q) + '0'; |
| 185 | q = (r * (uint64_t)0x1999999a) >> 32; | ||
| 186 | *buf++ = (r - 10 * q) + '0'; /* 4 */ | ||
| 187 | if (q == 0) | ||
| 188 | return buf; | ||
| 189 | r = (q * (uint64_t)0x1999999a) >> 32; | ||
| 190 | *buf++ = (q - 10 * r) + '0'; /* 5 */ | ||
| 191 | if (r == 0) | ||
| 192 | return buf; | ||
| 193 | q = (r * 0x199a) >> 16; | ||
| 194 | *buf++ = (r - 10 * q) + '0'; /* 6 */ | ||
| 195 | if (q == 0) | 185 | if (q == 0) |
| 196 | return buf; | 186 | return buf; |
| 197 | r = (q * 0xcd) >> 11; | 187 | r = (q * 0xcd) >> 11; /* q <= 999 */ |
| 198 | *buf++ = (q - 10 * r) + '0'; /* 7 */ | 188 | *buf++ = (q - 10 * r) + '0'; |
| 199 | if (r == 0) | 189 | if (r == 0) |
| 200 | return buf; | 190 | return buf; |
| 201 | q = (r * 0xcd) >> 11; | 191 | q = (r * 0xcd) >> 11; /* r <= 99 */ |
| 202 | *buf++ = (r - 10 * q) + '0'; /* 8 */ | 192 | *buf++ = (r - 10 * q) + '0'; |
| 203 | if (q == 0) | 193 | if (q == 0) |
| 204 | return buf; | 194 | return buf; |
| 205 | *buf++ = q + '0'; /* 9 */ | 195 | *buf++ = q + '0'; /* q <= 9 */ |
| 206 | return buf; | 196 | return buf; |
| 207 | } | 197 | } |
| 208 | 198 | ||
| @@ -243,18 +233,34 @@ char *put_dec(char *buf, unsigned long long n) | |||
| 243 | 233 | ||
| 244 | /* Second algorithm: valid only for 64-bit long longs */ | 234 | /* Second algorithm: valid only for 64-bit long longs */ |
| 245 | 235 | ||
| 236 | /* See comment in put_dec_full9 for choice of constants */ | ||
| 246 | static noinline_for_stack | 237 | static noinline_for_stack |
| 247 | char *put_dec_full4(char *buf, unsigned q) | 238 | void put_dec_full4(char *buf, unsigned q) |
| 248 | { | 239 | { |
| 249 | unsigned r; | 240 | unsigned r; |
| 250 | r = (q * 0xcccd) >> 19; | 241 | r = (q * 0xccd) >> 15; |
| 251 | *buf++ = (q - 10 * r) + '0'; | 242 | buf[0] = (q - 10 * r) + '0'; |
| 252 | q = (r * 0x199a) >> 16; | 243 | q = (r * 0xcd) >> 11; |
| 253 | *buf++ = (r - 10 * q) + '0'; | 244 | buf[1] = (r - 10 * q) + '0'; |
| 254 | r = (q * 0xcd) >> 11; | 245 | r = (q * 0xcd) >> 11; |
| 255 | *buf++ = (q - 10 * r) + '0'; | 246 | buf[2] = (q - 10 * r) + '0'; |
| 256 | *buf++ = r + '0'; | 247 | buf[3] = r + '0'; |
| 257 | return buf; | 248 | } |
| 249 | |||
| 250 | /* | ||
| 251 | * Call put_dec_full4 on x % 10000, return x / 10000. | ||
| 252 | * The approximation x/10000 == (x * 0x346DC5D7) >> 43 | ||
| 253 | * holds for all x < 1,128,869,999. The largest value this | ||
| 254 | * helper will ever be asked to convert is 1,125,520,955. | ||
| 255 | * (d1 in the put_dec code, assuming n is all-ones). | ||
| 256 | */ | ||
| 257 | static | ||
| 258 | unsigned put_dec_helper4(char *buf, unsigned x) | ||
| 259 | { | ||
| 260 | uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43; | ||
| 261 | |||
| 262 | put_dec_full4(buf, x - q * 10000); | ||
| 263 | return q; | ||
| 258 | } | 264 | } |
| 259 | 265 | ||
| 260 | /* Based on code by Douglas W. Jones found at | 266 | /* Based on code by Douglas W. Jones found at |
| @@ -276,28 +282,19 @@ char *put_dec(char *buf, unsigned long long n) | |||
| 276 | d3 = (h >> 16); /* implicit "& 0xffff" */ | 282 | d3 = (h >> 16); /* implicit "& 0xffff" */ |
| 277 | 283 | ||
| 278 | q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); | 284 | q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); |
| 285 | q = put_dec_helper4(buf, q); | ||
| 286 | |||
| 287 | q += 7671 * d3 + 9496 * d2 + 6 * d1; | ||
| 288 | q = put_dec_helper4(buf+4, q); | ||
| 289 | |||
| 290 | q += 4749 * d3 + 42 * d2; | ||
| 291 | q = put_dec_helper4(buf+8, q); | ||
| 279 | 292 | ||
| 280 | buf = put_dec_full4(buf, q % 10000); | 293 | q += 281 * d3; |
| 281 | q = q / 10000; | 294 | buf += 12; |
| 282 | 295 | if (q) | |
| 283 | d1 = q + 7671 * d3 + 9496 * d2 + 6 * d1; | 296 | buf = put_dec_trunc8(buf, q); |
| 284 | buf = put_dec_full4(buf, d1 % 10000); | 297 | else while (buf[-1] == '0') |
| 285 | q = d1 / 10000; | ||
| 286 | |||
| 287 | d2 = q + 4749 * d3 + 42 * d2; | ||
| 288 | buf = put_dec_full4(buf, d2 % 10000); | ||
| 289 | q = d2 / 10000; | ||
| 290 | |||
| 291 | d3 = q + 281 * d3; | ||
| 292 | if (!d3) | ||
| 293 | goto done; | ||
| 294 | buf = put_dec_full4(buf, d3 % 10000); | ||
| 295 | q = d3 / 10000; | ||
| 296 | if (!q) | ||
| 297 | goto done; | ||
| 298 | buf = put_dec_full4(buf, q); | ||
| 299 | done: | ||
| 300 | while (buf[-1] == '0') | ||
| 301 | --buf; | 298 | --buf; |
| 302 | 299 | ||
| 303 | return buf; | 300 | return buf; |
| @@ -990,7 +987,7 @@ int kptr_restrict __read_mostly; | |||
| 990 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons | 987 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons |
| 991 | * - 'MF' For a 6-byte MAC FDDI address, it prints the address | 988 | * - 'MF' For a 6-byte MAC FDDI address, it prints the address |
| 992 | * with a dash-separated hex notation | 989 | * with a dash-separated hex notation |
| 993 | * - '[mM]R For a 6-byte MAC address, Reverse order (Bluetooth) | 990 | * - '[mM]R' For a 6-byte MAC address, Reverse order (Bluetooth) |
| 994 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way | 991 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way |
| 995 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) | 992 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) |
| 996 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's | 993 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's |
| @@ -1341,7 +1338,10 @@ qualifier: | |||
| 1341 | * %pR output the address range in a struct resource with decoded flags | 1338 | * %pR output the address range in a struct resource with decoded flags |
| 1342 | * %pr output the address range in a struct resource with raw flags | 1339 | * %pr output the address range in a struct resource with raw flags |
| 1343 | * %pM output a 6-byte MAC address with colons | 1340 | * %pM output a 6-byte MAC address with colons |
| 1341 | * %pMR output a 6-byte MAC address with colons in reversed order | ||
| 1342 | * %pMF output a 6-byte MAC address with dashes | ||
| 1344 | * %pm output a 6-byte MAC address without colons | 1343 | * %pm output a 6-byte MAC address without colons |
| 1344 | * %pmR output a 6-byte MAC address without colons in reversed order | ||
| 1345 | * %pI4 print an IPv4 address without leading zeros | 1345 | * %pI4 print an IPv4 address without leading zeros |
| 1346 | * %pi4 print an IPv4 address with leading zeros | 1346 | * %pi4 print an IPv4 address with leading zeros |
| 1347 | * %pI6 print an IPv6 address with colons | 1347 | * %pI6 print an IPv6 address with colons |
| @@ -2017,7 +2017,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
| 2017 | s16 field_width; | 2017 | s16 field_width; |
| 2018 | bool is_sign; | 2018 | bool is_sign; |
| 2019 | 2019 | ||
| 2020 | while (*fmt && *str) { | 2020 | while (*fmt) { |
| 2021 | /* skip any white space in format */ | 2021 | /* skip any white space in format */ |
| 2022 | /* white space in format matchs any amount of | 2022 | /* white space in format matchs any amount of |
| 2023 | * white space, including none, in the input. | 2023 | * white space, including none, in the input. |
| @@ -2042,6 +2042,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
| 2042 | * advance both strings to next white space | 2042 | * advance both strings to next white space |
| 2043 | */ | 2043 | */ |
| 2044 | if (*fmt == '*') { | 2044 | if (*fmt == '*') { |
| 2045 | if (!*str) | ||
| 2046 | break; | ||
| 2045 | while (!isspace(*fmt) && *fmt != '%' && *fmt) | 2047 | while (!isspace(*fmt) && *fmt != '%' && *fmt) |
| 2046 | fmt++; | 2048 | fmt++; |
| 2047 | while (!isspace(*str) && *str) | 2049 | while (!isspace(*str) && *str) |
| @@ -2070,7 +2072,17 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
| 2070 | } | 2072 | } |
| 2071 | } | 2073 | } |
| 2072 | 2074 | ||
| 2073 | if (!*fmt || !*str) | 2075 | if (!*fmt) |
| 2076 | break; | ||
| 2077 | |||
| 2078 | if (*fmt == 'n') { | ||
| 2079 | /* return number of characters read so far */ | ||
| 2080 | *va_arg(args, int *) = str - buf; | ||
| 2081 | ++fmt; | ||
| 2082 | continue; | ||
| 2083 | } | ||
| 2084 | |||
| 2085 | if (!*str) | ||
| 2074 | break; | 2086 | break; |
| 2075 | 2087 | ||
| 2076 | base = 10; | 2088 | base = 10; |
| @@ -2103,13 +2115,6 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
| 2103 | num++; | 2115 | num++; |
| 2104 | } | 2116 | } |
| 2105 | continue; | 2117 | continue; |
| 2106 | case 'n': | ||
| 2107 | /* return number of characters read so far */ | ||
| 2108 | { | ||
| 2109 | int *i = (int *)va_arg(args, int*); | ||
| 2110 | *i = str - buf; | ||
| 2111 | } | ||
| 2112 | continue; | ||
| 2113 | case 'o': | 2118 | case 'o': |
| 2114 | base = 8; | 2119 | base = 8; |
| 2115 | break; | 2120 | break; |
| @@ -2210,16 +2215,6 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
| 2210 | str = next; | 2215 | str = next; |
| 2211 | } | 2216 | } |
| 2212 | 2217 | ||
| 2213 | /* | ||
| 2214 | * Now we've come all the way through so either the input string or the | ||
| 2215 | * format ended. In the former case, there can be a %n at the current | ||
| 2216 | * position in the format that needs to be filled. | ||
| 2217 | */ | ||
| 2218 | if (*fmt == '%' && *(fmt + 1) == 'n') { | ||
| 2219 | int *p = (int *)va_arg(args, int *); | ||
| 2220 | *p = str - buf; | ||
| 2221 | } | ||
| 2222 | |||
| 2223 | return num; | 2218 | return num; |
| 2224 | } | 2219 | } |
| 2225 | EXPORT_SYMBOL(vsscanf); | 2220 | EXPORT_SYMBOL(vsscanf); |
