aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig7
-rw-r--r--lib/Kconfig.debug23
-rw-r--r--lib/Kconfig.kgdb3
-rw-r--r--lib/Makefile15
-rw-r--r--lib/crc-t10dif.c67
-rw-r--r--lib/kobject.c11
-rw-r--r--lib/kobject_uevent.c3
-rw-r--r--lib/scatterlist.c176
-rw-r--r--lib/textsearch.c17
-rw-r--r--lib/ts_bm.c26
-rw-r--r--lib/ts_fsm.c6
-rw-r--r--lib/ts_kmp.c29
12 files changed, 299 insertions, 84 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 8cc8e8722a3f..c7ad7a5b3535 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -29,6 +29,13 @@ config CRC16
29 the kernel tree does. Such modules that use library CRC16 29 the kernel tree does. Such modules that use library CRC16
30 functions require M here. 30 functions require M here.
31 31
32config CRC_T10DIF
33 tristate "CRC calculation for the T10 Data Integrity Field"
34 help
35 This option is only needed if a module that's not in the
36 kernel tree needs to calculate CRC checks for use with the
37 SCSI data integrity subsystem.
38
32config CRC_ITU_T 39config CRC_ITU_T
33 tristate "CRC ITU-T V.41 functions" 40 tristate "CRC ITU-T V.41 functions"
34 help 41 help
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 011e00bcfc30..882c51048993 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -74,6 +74,9 @@ config DEBUG_FS
74 debugging files into. Enable this option to be able to read and 74 debugging files into. Enable this option to be able to read and
75 write to these files. 75 write to these files.
76 76
77 For detailed documentation on the debugfs API, see
78 Documentation/DocBook/filesystems.
79
77 If unsure, say N. 80 If unsure, say N.
78 81
79config HEADERS_CHECK 82config HEADERS_CHECK
@@ -554,16 +557,34 @@ config BOOT_PRINTK_DELAY
554config RCU_TORTURE_TEST 557config RCU_TORTURE_TEST
555 tristate "torture tests for RCU" 558 tristate "torture tests for RCU"
556 depends on DEBUG_KERNEL 559 depends on DEBUG_KERNEL
557 depends on m
558 default n 560 default n
559 help 561 help
560 This option provides a kernel module that runs torture tests 562 This option provides a kernel module that runs torture tests
561 on the RCU infrastructure. The kernel module may be built 563 on the RCU infrastructure. The kernel module may be built
562 after the fact on the running kernel to be tested, if desired. 564 after the fact on the running kernel to be tested, if desired.
563 565
566 Say Y here if you want RCU torture tests to be built into
567 the kernel.
564 Say M if you want the RCU torture tests to build as a module. 568 Say M if you want the RCU torture tests to build as a module.
565 Say N if you are unsure. 569 Say N if you are unsure.
566 570
571config RCU_TORTURE_TEST_RUNNABLE
572 bool "torture tests for RCU runnable by default"
573 depends on RCU_TORTURE_TEST = y
574 default n
575 help
576 This option provides a way to build the RCU torture tests
577 directly into the kernel without them starting up at boot
578 time. You can use /proc/sys/kernel/rcutorture_runnable
579 to manually override this setting. This /proc file is
580 available only when the RCU torture tests have been built
581 into the kernel.
582
583 Say Y here if you want the RCU torture tests to start during
584 boot (you probably don't).
585 Say N here if you want the RCU torture tests to start only
586 after being manually enabled via /proc.
587
567config KPROBES_SANITY_TEST 588config KPROBES_SANITY_TEST
568 bool "Kprobes sanity tests" 589 bool "Kprobes sanity tests"
569 depends on DEBUG_KERNEL 590 depends on DEBUG_KERNEL
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb
index a5d4b1dac2a5..2cfd2721f7ed 100644
--- a/lib/Kconfig.kgdb
+++ b/lib/Kconfig.kgdb
@@ -1,7 +1,4 @@
1 1
2config HAVE_ARCH_KGDB_SHADOW_INFO
3 bool
4
5config HAVE_ARCH_KGDB 2config HAVE_ARCH_KGDB
6 bool 3 bool
7 4
diff --git a/lib/Makefile b/lib/Makefile
index 4b836a53c08f..818c4d455518 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -2,21 +2,17 @@
2# Makefile for some libs needed in the kernel. 2# Makefile for some libs needed in the kernel.
3# 3#
4 4
5ifdef CONFIG_FTRACE
6ORIG_CFLAGS := $(KBUILD_CFLAGS)
7KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS))
8endif
9
5lib-y := ctype.o string.o vsprintf.o cmdline.o \ 10lib-y := ctype.o string.o vsprintf.o cmdline.o \
6 rbtree.o radix-tree.o dump_stack.o \ 11 rbtree.o radix-tree.o dump_stack.o \
7 idr.o int_sqrt.o extable.o prio_tree.o \ 12 idr.o int_sqrt.o extable.o prio_tree.o \
8 sha1.o irq_regs.o reciprocal_div.o argv_split.o \ 13 sha1.o irq_regs.o reciprocal_div.o argv_split.o \
9 proportions.o prio_heap.o ratelimit.o 14 proportions.o prio_heap.o ratelimit.o
10 15
11ifdef CONFIG_FTRACE
12# Do not profile string.o, since it may be used in early boot or vdso
13CFLAGS_REMOVE_string.o = -pg
14# Also do not profile any debug utilities
15CFLAGS_REMOVE_spinlock_debug.o = -pg
16CFLAGS_REMOVE_list_debug.o = -pg
17CFLAGS_REMOVE_debugobjects.o = -pg
18endif
19
20lib-$(CONFIG_MMU) += ioremap.o 16lib-$(CONFIG_MMU) += ioremap.o
21lib-$(CONFIG_SMP) += cpumask.o 17lib-$(CONFIG_SMP) += cpumask.o
22 18
@@ -54,6 +50,7 @@ endif
54obj-$(CONFIG_BITREVERSE) += bitrev.o 50obj-$(CONFIG_BITREVERSE) += bitrev.o
55obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o 51obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
56obj-$(CONFIG_CRC16) += crc16.o 52obj-$(CONFIG_CRC16) += crc16.o
53obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o
57obj-$(CONFIG_CRC_ITU_T) += crc-itu-t.o 54obj-$(CONFIG_CRC_ITU_T) += crc-itu-t.o
58obj-$(CONFIG_CRC32) += crc32.o 55obj-$(CONFIG_CRC32) += crc32.o
59obj-$(CONFIG_CRC7) += crc7.o 56obj-$(CONFIG_CRC7) += crc7.o
diff --git a/lib/crc-t10dif.c b/lib/crc-t10dif.c
new file mode 100644
index 000000000000..fbbd66ed86cd
--- /dev/null
+++ b/lib/crc-t10dif.c
@@ -0,0 +1,67 @@
1/*
2 * T10 Data Integrity Field CRC16 calculation
3 *
4 * Copyright (c) 2007 Oracle Corporation. All rights reserved.
5 * Written by Martin K. Petersen <martin.petersen@oracle.com>
6 *
7 * This source code is licensed under the GNU General Public License,
8 * Version 2. See the file COPYING for more details.
9 */
10
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/crc-t10dif.h>
14
15/* Table generated using the following polynomium:
16 * x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
17 * gt: 0x8bb7
18 */
19static const __u16 t10_dif_crc_table[256] = {
20 0x0000, 0x8BB7, 0x9CD9, 0x176E, 0xB205, 0x39B2, 0x2EDC, 0xA56B,
21 0xEFBD, 0x640A, 0x7364, 0xF8D3, 0x5DB8, 0xD60F, 0xC161, 0x4AD6,
22 0x54CD, 0xDF7A, 0xC814, 0x43A3, 0xE6C8, 0x6D7F, 0x7A11, 0xF1A6,
23 0xBB70, 0x30C7, 0x27A9, 0xAC1E, 0x0975, 0x82C2, 0x95AC, 0x1E1B,
24 0xA99A, 0x222D, 0x3543, 0xBEF4, 0x1B9F, 0x9028, 0x8746, 0x0CF1,
25 0x4627, 0xCD90, 0xDAFE, 0x5149, 0xF422, 0x7F95, 0x68FB, 0xE34C,
26 0xFD57, 0x76E0, 0x618E, 0xEA39, 0x4F52, 0xC4E5, 0xD38B, 0x583C,
27 0x12EA, 0x995D, 0x8E33, 0x0584, 0xA0EF, 0x2B58, 0x3C36, 0xB781,
28 0xD883, 0x5334, 0x445A, 0xCFED, 0x6A86, 0xE131, 0xF65F, 0x7DE8,
29 0x373E, 0xBC89, 0xABE7, 0x2050, 0x853B, 0x0E8C, 0x19E2, 0x9255,
30 0x8C4E, 0x07F9, 0x1097, 0x9B20, 0x3E4B, 0xB5FC, 0xA292, 0x2925,
31 0x63F3, 0xE844, 0xFF2A, 0x749D, 0xD1F6, 0x5A41, 0x4D2F, 0xC698,
32 0x7119, 0xFAAE, 0xEDC0, 0x6677, 0xC31C, 0x48AB, 0x5FC5, 0xD472,
33 0x9EA4, 0x1513, 0x027D, 0x89CA, 0x2CA1, 0xA716, 0xB078, 0x3BCF,
34 0x25D4, 0xAE63, 0xB90D, 0x32BA, 0x97D1, 0x1C66, 0x0B08, 0x80BF,
35 0xCA69, 0x41DE, 0x56B0, 0xDD07, 0x786C, 0xF3DB, 0xE4B5, 0x6F02,
36 0x3AB1, 0xB106, 0xA668, 0x2DDF, 0x88B4, 0x0303, 0x146D, 0x9FDA,
37 0xD50C, 0x5EBB, 0x49D5, 0xC262, 0x6709, 0xECBE, 0xFBD0, 0x7067,
38 0x6E7C, 0xE5CB, 0xF2A5, 0x7912, 0xDC79, 0x57CE, 0x40A0, 0xCB17,
39 0x81C1, 0x0A76, 0x1D18, 0x96AF, 0x33C4, 0xB873, 0xAF1D, 0x24AA,
40 0x932B, 0x189C, 0x0FF2, 0x8445, 0x212E, 0xAA99, 0xBDF7, 0x3640,
41 0x7C96, 0xF721, 0xE04F, 0x6BF8, 0xCE93, 0x4524, 0x524A, 0xD9FD,
42 0xC7E6, 0x4C51, 0x5B3F, 0xD088, 0x75E3, 0xFE54, 0xE93A, 0x628D,
43 0x285B, 0xA3EC, 0xB482, 0x3F35, 0x9A5E, 0x11E9, 0x0687, 0x8D30,
44 0xE232, 0x6985, 0x7EEB, 0xF55C, 0x5037, 0xDB80, 0xCCEE, 0x4759,
45 0x0D8F, 0x8638, 0x9156, 0x1AE1, 0xBF8A, 0x343D, 0x2353, 0xA8E4,
46 0xB6FF, 0x3D48, 0x2A26, 0xA191, 0x04FA, 0x8F4D, 0x9823, 0x1394,
47 0x5942, 0xD2F5, 0xC59B, 0x4E2C, 0xEB47, 0x60F0, 0x779E, 0xFC29,
48 0x4BA8, 0xC01F, 0xD771, 0x5CC6, 0xF9AD, 0x721A, 0x6574, 0xEEC3,
49 0xA415, 0x2FA2, 0x38CC, 0xB37B, 0x1610, 0x9DA7, 0x8AC9, 0x017E,
50 0x1F65, 0x94D2, 0x83BC, 0x080B, 0xAD60, 0x26D7, 0x31B9, 0xBA0E,
51 0xF0D8, 0x7B6F, 0x6C01, 0xE7B6, 0x42DD, 0xC96A, 0xDE04, 0x55B3
52};
53
54__u16 crc_t10dif(const unsigned char *buffer, size_t len)
55{
56 __u16 crc = 0;
57 unsigned int i;
58
59 for (i = 0 ; i < len ; i++)
60 crc = (crc << 8) ^ t10_dif_crc_table[((crc >> 8) ^ buffer[i]) & 0xff];
61
62 return crc;
63}
64EXPORT_SYMBOL(crc_t10dif);
65
66MODULE_DESCRIPTION("T10 DIF CRC calculation");
67MODULE_LICENSE("GPL");
diff --git a/lib/kobject.c b/lib/kobject.c
index 718e5101c263..744401571ed7 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -216,13 +216,19 @@ static int kobject_add_internal(struct kobject *kobj)
216static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, 216static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
217 va_list vargs) 217 va_list vargs)
218{ 218{
219 /* Free the old name, if necessary. */ 219 const char *old_name = kobj->name;
220 kfree(kobj->name); 220 char *s;
221 221
222 kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs); 222 kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
223 if (!kobj->name) 223 if (!kobj->name)
224 return -ENOMEM; 224 return -ENOMEM;
225 225
226 /* ewww... some of these buggers have '/' in the name ... */
227 s = strchr(kobj->name, '/');
228 if (s)
229 s[0] = '!';
230
231 kfree(old_name);
226 return 0; 232 return 0;
227} 233}
228 234
@@ -439,6 +445,7 @@ out:
439 445
440 return error; 446 return error;
441} 447}
448EXPORT_SYMBOL_GPL(kobject_rename);
442 449
443/** 450/**
444 * kobject_move - move object to another parent 451 * kobject_move - move object to another parent
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 2fa545a63160..9f8d599459d1 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -245,7 +245,8 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
245 if (retval) 245 if (retval)
246 goto exit; 246 goto exit;
247 247
248 call_usermodehelper(argv[0], argv, env->envp, UMH_WAIT_EXEC); 248 retval = call_usermodehelper(argv[0], argv,
249 env->envp, UMH_WAIT_EXEC);
249 } 250 }
250 251
251exit: 252exit:
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index b80c21100d78..876ba6d5b670 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -295,6 +295,117 @@ int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
295EXPORT_SYMBOL(sg_alloc_table); 295EXPORT_SYMBOL(sg_alloc_table);
296 296
297/** 297/**
298 * sg_miter_start - start mapping iteration over a sg list
299 * @miter: sg mapping iter to be started
300 * @sgl: sg list to iterate over
301 * @nents: number of sg entries
302 *
303 * Description:
304 * Starts mapping iterator @miter.
305 *
306 * Context:
307 * Don't care.
308 */
309void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
310 unsigned int nents, unsigned int flags)
311{
312 memset(miter, 0, sizeof(struct sg_mapping_iter));
313
314 miter->__sg = sgl;
315 miter->__nents = nents;
316 miter->__offset = 0;
317 miter->__flags = flags;
318}
319EXPORT_SYMBOL(sg_miter_start);
320
321/**
322 * sg_miter_next - proceed mapping iterator to the next mapping
323 * @miter: sg mapping iter to proceed
324 *
325 * Description:
326 * Proceeds @miter@ to the next mapping. @miter@ should have been
327 * started using sg_miter_start(). On successful return,
328 * @miter@->page, @miter@->addr and @miter@->length point to the
329 * current mapping.
330 *
331 * Context:
332 * IRQ disabled if SG_MITER_ATOMIC. IRQ must stay disabled till
333 * @miter@ is stopped. May sleep if !SG_MITER_ATOMIC.
334 *
335 * Returns:
336 * true if @miter contains the next mapping. false if end of sg
337 * list is reached.
338 */
339bool sg_miter_next(struct sg_mapping_iter *miter)
340{
341 unsigned int off, len;
342
343 /* check for end and drop resources from the last iteration */
344 if (!miter->__nents)
345 return false;
346
347 sg_miter_stop(miter);
348
349 /* get to the next sg if necessary. __offset is adjusted by stop */
350 if (miter->__offset == miter->__sg->length && --miter->__nents) {
351 miter->__sg = sg_next(miter->__sg);
352 miter->__offset = 0;
353 }
354
355 /* map the next page */
356 off = miter->__sg->offset + miter->__offset;
357 len = miter->__sg->length - miter->__offset;
358
359 miter->page = nth_page(sg_page(miter->__sg), off >> PAGE_SHIFT);
360 off &= ~PAGE_MASK;
361 miter->length = min_t(unsigned int, len, PAGE_SIZE - off);
362 miter->consumed = miter->length;
363
364 if (miter->__flags & SG_MITER_ATOMIC)
365 miter->addr = kmap_atomic(miter->page, KM_BIO_SRC_IRQ) + off;
366 else
367 miter->addr = kmap(miter->page) + off;
368
369 return true;
370}
371EXPORT_SYMBOL(sg_miter_next);
372
373/**
374 * sg_miter_stop - stop mapping iteration
375 * @miter: sg mapping iter to be stopped
376 *
377 * Description:
378 * Stops mapping iterator @miter. @miter should have been started
379 * started using sg_miter_start(). A stopped iteration can be
380 * resumed by calling sg_miter_next() on it. This is useful when
381 * resources (kmap) need to be released during iteration.
382 *
383 * Context:
384 * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise.
385 */
386void sg_miter_stop(struct sg_mapping_iter *miter)
387{
388 WARN_ON(miter->consumed > miter->length);
389
390 /* drop resources from the last iteration */
391 if (miter->addr) {
392 miter->__offset += miter->consumed;
393
394 if (miter->__flags & SG_MITER_ATOMIC) {
395 WARN_ON(!irqs_disabled());
396 kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ);
397 } else
398 kunmap(miter->addr);
399
400 miter->page = NULL;
401 miter->addr = NULL;
402 miter->length = 0;
403 miter->consumed = 0;
404 }
405}
406EXPORT_SYMBOL(sg_miter_stop);
407
408/**
298 * sg_copy_buffer - Copy data between a linear buffer and an SG list 409 * sg_copy_buffer - Copy data between a linear buffer and an SG list
299 * @sgl: The SG list 410 * @sgl: The SG list
300 * @nents: Number of SG entries 411 * @nents: Number of SG entries
@@ -309,56 +420,29 @@ EXPORT_SYMBOL(sg_alloc_table);
309static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, 420static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
310 void *buf, size_t buflen, int to_buffer) 421 void *buf, size_t buflen, int to_buffer)
311{ 422{
312 struct scatterlist *sg; 423 unsigned int offset = 0;
313 size_t buf_off = 0; 424 struct sg_mapping_iter miter;
314 int i; 425
315 426 sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC);
316 WARN_ON(!irqs_disabled()); 427
317 428 while (sg_miter_next(&miter) && offset < buflen) {
318 for_each_sg(sgl, sg, nents, i) { 429 unsigned int len;
319 struct page *page; 430
320 int n = 0; 431 len = min(miter.length, buflen - offset);
321 unsigned int sg_off = sg->offset; 432
322 unsigned int sg_copy = sg->length; 433 if (to_buffer)
323 434 memcpy(buf + offset, miter.addr, len);
324 if (sg_copy > buflen) 435 else {
325 sg_copy = buflen; 436 memcpy(miter.addr, buf + offset, len);
326 buflen -= sg_copy; 437 flush_kernel_dcache_page(miter.page);
327
328 while (sg_copy > 0) {
329 unsigned int page_copy;
330 void *p;
331
332 page_copy = PAGE_SIZE - sg_off;
333 if (page_copy > sg_copy)
334 page_copy = sg_copy;
335
336 page = nth_page(sg_page(sg), n);
337 p = kmap_atomic(page, KM_BIO_SRC_IRQ);
338
339 if (to_buffer)
340 memcpy(buf + buf_off, p + sg_off, page_copy);
341 else {
342 memcpy(p + sg_off, buf + buf_off, page_copy);
343 flush_kernel_dcache_page(page);
344 }
345
346 kunmap_atomic(p, KM_BIO_SRC_IRQ);
347
348 buf_off += page_copy;
349 sg_off += page_copy;
350 if (sg_off == PAGE_SIZE) {
351 sg_off = 0;
352 n++;
353 }
354 sg_copy -= page_copy;
355 } 438 }
356 439
357 if (!buflen) 440 offset += len;
358 break;
359 } 441 }
360 442
361 return buf_off; 443 sg_miter_stop(&miter);
444
445 return offset;
362} 446}
363 447
364/** 448/**
diff --git a/lib/textsearch.c b/lib/textsearch.c
index be8bda3862f5..9fbcb44c554f 100644
--- a/lib/textsearch.c
+++ b/lib/textsearch.c
@@ -54,10 +54,13 @@
54 * USAGE 54 * USAGE
55 * 55 *
56 * Before a search can be performed, a configuration must be created 56 * Before a search can be performed, a configuration must be created
57 * by calling textsearch_prepare() specyfing the searching algorithm and 57 * by calling textsearch_prepare() specifying the searching algorithm,
58 * the pattern to look for. The returned configuration may then be used 58 * the pattern to look for and flags. As a flag, you can set TS_IGNORECASE
59 * for an arbitary amount of times and even in parallel as long as a 59 * to perform case insensitive matching. But it might slow down
60 * separate struct ts_state variable is provided to every instance. 60 * performance of algorithm, so you should use it at own your risk.
61 * The returned configuration may then be used for an arbitary
62 * amount of times and even in parallel as long as a separate struct
63 * ts_state variable is provided to every instance.
61 * 64 *
62 * The actual search is performed by either calling textsearch_find_- 65 * The actual search is performed by either calling textsearch_find_-
63 * continuous() for linear data or by providing an own get_next_block() 66 * continuous() for linear data or by providing an own get_next_block()
@@ -89,7 +92,6 @@
89 * panic("Oh my god, dancing chickens at %d\n", pos); 92 * panic("Oh my god, dancing chickens at %d\n", pos);
90 * 93 *
91 * textsearch_destroy(conf); 94 * textsearch_destroy(conf);
92 *
93 * ========================================================================== 95 * ==========================================================================
94 */ 96 */
95 97
@@ -97,6 +99,7 @@
97#include <linux/types.h> 99#include <linux/types.h>
98#include <linux/string.h> 100#include <linux/string.h>
99#include <linux/init.h> 101#include <linux/init.h>
102#include <linux/rculist.h>
100#include <linux/rcupdate.h> 103#include <linux/rcupdate.h>
101#include <linux/err.h> 104#include <linux/err.h>
102#include <linux/textsearch.h> 105#include <linux/textsearch.h>
@@ -264,7 +267,7 @@ struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
264 return ERR_PTR(-EINVAL); 267 return ERR_PTR(-EINVAL);
265 268
266 ops = lookup_ts_algo(algo); 269 ops = lookup_ts_algo(algo);
267#ifdef CONFIG_KMOD 270#ifdef CONFIG_MODULES
268 /* 271 /*
269 * Why not always autoload you may ask. Some users are 272 * Why not always autoload you may ask. Some users are
270 * in a situation where requesting a module may deadlock, 273 * in a situation where requesting a module may deadlock,
@@ -279,7 +282,7 @@ struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
279 if (ops == NULL) 282 if (ops == NULL)
280 goto errout; 283 goto errout;
281 284
282 conf = ops->init(pattern, len, gfp_mask); 285 conf = ops->init(pattern, len, gfp_mask, flags);
283 if (IS_ERR(conf)) { 286 if (IS_ERR(conf)) {
284 err = PTR_ERR(conf); 287 err = PTR_ERR(conf);
285 goto errout; 288 goto errout;
diff --git a/lib/ts_bm.c b/lib/ts_bm.c
index 4a7fce72898e..9e66ee4020e9 100644
--- a/lib/ts_bm.c
+++ b/lib/ts_bm.c
@@ -39,6 +39,7 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/types.h> 40#include <linux/types.h>
41#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/ctype.h>
42#include <linux/textsearch.h> 43#include <linux/textsearch.h>
43 44
44/* Alphabet size, use ASCII */ 45/* Alphabet size, use ASCII */
@@ -64,6 +65,7 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
64 unsigned int i, text_len, consumed = state->offset; 65 unsigned int i, text_len, consumed = state->offset;
65 const u8 *text; 66 const u8 *text;
66 int shift = bm->patlen - 1, bs; 67 int shift = bm->patlen - 1, bs;
68 const u8 icase = conf->flags & TS_IGNORECASE;
67 69
68 for (;;) { 70 for (;;) {
69 text_len = conf->get_next_block(consumed, &text, conf, state); 71 text_len = conf->get_next_block(consumed, &text, conf, state);
@@ -75,7 +77,9 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
75 DEBUGP("Searching in position %d (%c)\n", 77 DEBUGP("Searching in position %d (%c)\n",
76 shift, text[shift]); 78 shift, text[shift]);
77 for (i = 0; i < bm->patlen; i++) 79 for (i = 0; i < bm->patlen; i++)
78 if (text[shift-i] != bm->pattern[bm->patlen-1-i]) 80 if ((icase ? toupper(text[shift-i])
81 : text[shift-i])
82 != bm->pattern[bm->patlen-1-i])
79 goto next; 83 goto next;
80 84
81 /* London calling... */ 85 /* London calling... */
@@ -111,14 +115,18 @@ static int subpattern(u8 *pattern, int i, int j, int g)
111 return ret; 115 return ret;
112} 116}
113 117
114static void compute_prefix_tbl(struct ts_bm *bm) 118static void compute_prefix_tbl(struct ts_bm *bm, int flags)
115{ 119{
116 int i, j, g; 120 int i, j, g;
117 121
118 for (i = 0; i < ASIZE; i++) 122 for (i = 0; i < ASIZE; i++)
119 bm->bad_shift[i] = bm->patlen; 123 bm->bad_shift[i] = bm->patlen;
120 for (i = 0; i < bm->patlen - 1; i++) 124 for (i = 0; i < bm->patlen - 1; i++) {
121 bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i; 125 bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i;
126 if (flags & TS_IGNORECASE)
127 bm->bad_shift[tolower(bm->pattern[i])]
128 = bm->patlen - 1 - i;
129 }
122 130
123 /* Compute the good shift array, used to match reocurrences 131 /* Compute the good shift array, used to match reocurrences
124 * of a subpattern */ 132 * of a subpattern */
@@ -135,10 +143,11 @@ static void compute_prefix_tbl(struct ts_bm *bm)
135} 143}
136 144
137static struct ts_config *bm_init(const void *pattern, unsigned int len, 145static struct ts_config *bm_init(const void *pattern, unsigned int len,
138 gfp_t gfp_mask) 146 gfp_t gfp_mask, int flags)
139{ 147{
140 struct ts_config *conf; 148 struct ts_config *conf;
141 struct ts_bm *bm; 149 struct ts_bm *bm;
150 int i;
142 unsigned int prefix_tbl_len = len * sizeof(unsigned int); 151 unsigned int prefix_tbl_len = len * sizeof(unsigned int);
143 size_t priv_size = sizeof(*bm) + len + prefix_tbl_len; 152 size_t priv_size = sizeof(*bm) + len + prefix_tbl_len;
144 153
@@ -146,11 +155,16 @@ static struct ts_config *bm_init(const void *pattern, unsigned int len,
146 if (IS_ERR(conf)) 155 if (IS_ERR(conf))
147 return conf; 156 return conf;
148 157
158 conf->flags = flags;
149 bm = ts_config_priv(conf); 159 bm = ts_config_priv(conf);
150 bm->patlen = len; 160 bm->patlen = len;
151 bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len; 161 bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len;
152 memcpy(bm->pattern, pattern, len); 162 if (flags & TS_IGNORECASE)
153 compute_prefix_tbl(bm); 163 for (i = 0; i < len; i++)
164 bm->pattern[i] = toupper(((u8 *)pattern)[i]);
165 else
166 memcpy(bm->pattern, pattern, len);
167 compute_prefix_tbl(bm, flags);
154 168
155 return conf; 169 return conf;
156} 170}
diff --git a/lib/ts_fsm.c b/lib/ts_fsm.c
index af575b61526b..5696a35184e4 100644
--- a/lib/ts_fsm.c
+++ b/lib/ts_fsm.c
@@ -257,7 +257,7 @@ found_match:
257} 257}
258 258
259static struct ts_config *fsm_init(const void *pattern, unsigned int len, 259static struct ts_config *fsm_init(const void *pattern, unsigned int len,
260 gfp_t gfp_mask) 260 gfp_t gfp_mask, int flags)
261{ 261{
262 int i, err = -EINVAL; 262 int i, err = -EINVAL;
263 struct ts_config *conf; 263 struct ts_config *conf;
@@ -269,6 +269,9 @@ static struct ts_config *fsm_init(const void *pattern, unsigned int len,
269 if (len % sizeof(struct ts_fsm_token) || ntokens < 1) 269 if (len % sizeof(struct ts_fsm_token) || ntokens < 1)
270 goto errout; 270 goto errout;
271 271
272 if (flags & TS_IGNORECASE)
273 goto errout;
274
272 for (i = 0; i < ntokens; i++) { 275 for (i = 0; i < ntokens; i++) {
273 struct ts_fsm_token *t = &tokens[i]; 276 struct ts_fsm_token *t = &tokens[i];
274 277
@@ -284,6 +287,7 @@ static struct ts_config *fsm_init(const void *pattern, unsigned int len,
284 if (IS_ERR(conf)) 287 if (IS_ERR(conf))
285 return conf; 288 return conf;
286 289
290 conf->flags = flags;
287 fsm = ts_config_priv(conf); 291 fsm = ts_config_priv(conf);
288 fsm->ntokens = ntokens; 292 fsm->ntokens = ntokens;
289 memcpy(fsm->tokens, pattern, len); 293 memcpy(fsm->tokens, pattern, len);
diff --git a/lib/ts_kmp.c b/lib/ts_kmp.c
index 3ced628cab4b..632f783e65f1 100644
--- a/lib/ts_kmp.c
+++ b/lib/ts_kmp.c
@@ -33,6 +33,7 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/string.h> 35#include <linux/string.h>
36#include <linux/ctype.h>
36#include <linux/textsearch.h> 37#include <linux/textsearch.h>
37 38
38struct ts_kmp 39struct ts_kmp
@@ -47,6 +48,7 @@ static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state)
47 struct ts_kmp *kmp = ts_config_priv(conf); 48 struct ts_kmp *kmp = ts_config_priv(conf);
48 unsigned int i, q = 0, text_len, consumed = state->offset; 49 unsigned int i, q = 0, text_len, consumed = state->offset;
49 const u8 *text; 50 const u8 *text;
51 const int icase = conf->flags & TS_IGNORECASE;
50 52
51 for (;;) { 53 for (;;) {
52 text_len = conf->get_next_block(consumed, &text, conf, state); 54 text_len = conf->get_next_block(consumed, &text, conf, state);
@@ -55,9 +57,11 @@ static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state)
55 break; 57 break;
56 58
57 for (i = 0; i < text_len; i++) { 59 for (i = 0; i < text_len; i++) {
58 while (q > 0 && kmp->pattern[q] != text[i]) 60 while (q > 0 && kmp->pattern[q]
61 != (icase ? toupper(text[i]) : text[i]))
59 q = kmp->prefix_tbl[q - 1]; 62 q = kmp->prefix_tbl[q - 1];
60 if (kmp->pattern[q] == text[i]) 63 if (kmp->pattern[q]
64 == (icase ? toupper(text[i]) : text[i]))
61 q++; 65 q++;
62 if (unlikely(q == kmp->pattern_len)) { 66 if (unlikely(q == kmp->pattern_len)) {
63 state->offset = consumed + i + 1; 67 state->offset = consumed + i + 1;
@@ -72,24 +76,28 @@ static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state)
72} 76}
73 77
74static inline void compute_prefix_tbl(const u8 *pattern, unsigned int len, 78static inline void compute_prefix_tbl(const u8 *pattern, unsigned int len,
75 unsigned int *prefix_tbl) 79 unsigned int *prefix_tbl, int flags)
76{ 80{
77 unsigned int k, q; 81 unsigned int k, q;
82 const u8 icase = flags & TS_IGNORECASE;
78 83
79 for (k = 0, q = 1; q < len; q++) { 84 for (k = 0, q = 1; q < len; q++) {
80 while (k > 0 && pattern[k] != pattern[q]) 85 while (k > 0 && (icase ? toupper(pattern[k]) : pattern[k])
86 != (icase ? toupper(pattern[q]) : pattern[q]))
81 k = prefix_tbl[k-1]; 87 k = prefix_tbl[k-1];
82 if (pattern[k] == pattern[q]) 88 if ((icase ? toupper(pattern[k]) : pattern[k])
89 == (icase ? toupper(pattern[q]) : pattern[q]))
83 k++; 90 k++;
84 prefix_tbl[q] = k; 91 prefix_tbl[q] = k;
85 } 92 }
86} 93}
87 94
88static struct ts_config *kmp_init(const void *pattern, unsigned int len, 95static struct ts_config *kmp_init(const void *pattern, unsigned int len,
89 gfp_t gfp_mask) 96 gfp_t gfp_mask, int flags)
90{ 97{
91 struct ts_config *conf; 98 struct ts_config *conf;
92 struct ts_kmp *kmp; 99 struct ts_kmp *kmp;
100 int i;
93 unsigned int prefix_tbl_len = len * sizeof(unsigned int); 101 unsigned int prefix_tbl_len = len * sizeof(unsigned int);
94 size_t priv_size = sizeof(*kmp) + len + prefix_tbl_len; 102 size_t priv_size = sizeof(*kmp) + len + prefix_tbl_len;
95 103
@@ -97,11 +105,16 @@ static struct ts_config *kmp_init(const void *pattern, unsigned int len,
97 if (IS_ERR(conf)) 105 if (IS_ERR(conf))
98 return conf; 106 return conf;
99 107
108 conf->flags = flags;
100 kmp = ts_config_priv(conf); 109 kmp = ts_config_priv(conf);
101 kmp->pattern_len = len; 110 kmp->pattern_len = len;
102 compute_prefix_tbl(pattern, len, kmp->prefix_tbl); 111 compute_prefix_tbl(pattern, len, kmp->prefix_tbl, flags);
103 kmp->pattern = (u8 *) kmp->prefix_tbl + prefix_tbl_len; 112 kmp->pattern = (u8 *) kmp->prefix_tbl + prefix_tbl_len;
104 memcpy(kmp->pattern, pattern, len); 113 if (flags & TS_IGNORECASE)
114 for (i = 0; i < len; i++)
115 kmp->pattern[i] = toupper(((u8 *)pattern)[i]);
116 else
117 memcpy(kmp->pattern, pattern, len);
105 118
106 return conf; 119 return conf;
107} 120}