]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
lib/string.c: introduce memchr_inv()
authorAkinobu Mita <akinobu.mita@gmail.com>
Wed, 5 Oct 2011 00:42:56 +0000 (11:42 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 12 Oct 2011 06:32:04 +0000 (17:32 +1100)
memchr_inv() is mainly used to check whether the whole buffer is filled
with just a specified byte.

The function name and prototype are stolen from logfs and the
implementation is from SLUB.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Acked-by: Christoph Lameter <cl@linux-foundation.org>
Acked-by: Pekka Enberg <penberg@kernel.org>
Cc: Matt Mackall <mpm@selenic.com>
Acked-by: Joern Engel <joern@logfs.org>
Cc: Marcin Slusarz <marcin.slusarz@gmail.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/logfs/logfs.h
fs/logfs/super.c
include/linux/string.h
lib/string.c
mm/slub.c

index 68e4fd275a02b4984a290e6a43b95de654cc45cb..1ba6e21e59569a12646c7cfbd07c12846e098aea 100644 (file)
@@ -619,7 +619,6 @@ static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs,
 struct page *emergency_read_begin(struct address_space *mapping, pgoff_t index);
 void emergency_read_end(struct page *page);
 void logfs_crash_dump(struct super_block *sb);
-void *memchr_inv(const void *s, int c, size_t n);
 int logfs_statfs(struct dentry *dentry, struct kstatfs *stats);
 int logfs_check_ds(struct logfs_disk_super *ds);
 int logfs_write_sb(struct super_block *sb);
index 2e998b787261955368a9642ace4d9efbbac52b4a..50203fc5d4ec0640148118ef1dbe140756f927f4 100644 (file)
@@ -91,28 +91,6 @@ void logfs_crash_dump(struct super_block *sb)
        dump_segfile(sb);
 }
 
-/*
- * TODO: move to lib/string.c
- */
-/**
- * memchr_inv - Find a character in an area of memory.
- * @s: The memory area
- * @c: The byte to search for
- * @n: The size of the area.
- *
- * returns the address of the first character other than @c, or %NULL
- * if the whole buffer contains just @c.
- */
-void *memchr_inv(const void *s, int c, size_t n)
-{
-       const unsigned char *p = s;
-       while (n-- != 0)
-               if ((unsigned char)c != *p++)
-                       return (void *)(p - 1);
-
-       return NULL;
-}
-
 /*
  * FIXME: There should be a reserve for root, similar to ext2.
  */
index a176db2f2c854755c360202358a227b4f42435d3..e033564f10baec5b9b39a75c29f956f5d512e7c4 100644 (file)
@@ -114,6 +114,7 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
 #ifndef __HAVE_ARCH_MEMCHR
 extern void * memchr(const void *,int,__kernel_size_t);
 #endif
+void *memchr_inv(const void *s, int c, size_t n);
 
 extern char *kstrdup(const char *s, gfp_t gfp);
 extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
index 01fad9b203e192eb8a3299d669c29e11e4cf2e04..18f511194bc6f5dad04c15db689405ac00901309 100644 (file)
@@ -756,3 +756,57 @@ void *memchr(const void *s, int c, size_t n)
 }
 EXPORT_SYMBOL(memchr);
 #endif
+
+static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
+{
+       while (bytes) {
+               if (*start != value)
+                       return (void *)start;
+               start++;
+               bytes--;
+       }
+       return NULL;
+}
+
+/**
+ * memchr_inv - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first character other than @c, or %NULL
+ * if the whole buffer contains just @c.
+ */
+void *memchr_inv(const void *start, int c, size_t bytes)
+{
+       u8 value = c;
+       u64 value64;
+       unsigned int words, prefix;
+
+       if (bytes <= 16)
+               return check_bytes8(start, value, bytes);
+
+       value64 = value | value << 8 | value << 16 | value << 24;
+       value64 = (value64 & 0xffffffff) | value64 << 32;
+       prefix = 8 - ((unsigned long)start) % 8;
+
+       if (prefix) {
+               u8 *r = check_bytes8(start, value, prefix);
+               if (r)
+                       return r;
+               start += prefix;
+               bytes -= prefix;
+       }
+
+       words = bytes / 8;
+
+       while (words) {
+               if (*(u64 *)start != value64)
+                       return check_bytes8(start, value, 8);
+               start += 8;
+               words--;
+       }
+
+       return check_bytes8(start, value, bytes % 8);
+}
+EXPORT_SYMBOL(memchr_inv);
index bbec29e9d12cec49b9a28d09332042f097c2e6c7..60552d52f8476fb65ba12ca27574f7d71c731293 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -655,49 +655,6 @@ static void init_object(struct kmem_cache *s, void *object, u8 val)
                memset(p + s->objsize, val, s->inuse - s->objsize);
 }
 
-static u8 *check_bytes8(u8 *start, u8 value, unsigned int bytes)
-{
-       while (bytes) {
-               if (*start != value)
-                       return start;
-               start++;
-               bytes--;
-       }
-       return NULL;
-}
-
-static u8 *check_bytes(u8 *start, u8 value, unsigned int bytes)
-{
-       u64 value64;
-       unsigned int words, prefix;
-
-       if (bytes <= 16)
-               return check_bytes8(start, value, bytes);
-
-       value64 = value | value << 8 | value << 16 | value << 24;
-       value64 = (value64 & 0xffffffff) | value64 << 32;
-       prefix = 8 - ((unsigned long)start) % 8;
-
-       if (prefix) {
-               u8 *r = check_bytes8(start, value, prefix);
-               if (r)
-                       return r;
-               start += prefix;
-               bytes -= prefix;
-       }
-
-       words = bytes / 8;
-
-       while (words) {
-               if (*(u64 *)start != value64)
-                       return check_bytes8(start, value, 8);
-               start += 8;
-               words--;
-       }
-
-       return check_bytes8(start, value, bytes % 8);
-}
-
 static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
                                                void *from, void *to)
 {
@@ -712,7 +669,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
        u8 *fault;
        u8 *end;
 
-       fault = check_bytes(start, value, bytes);
+       fault = memchr_inv(start, value, bytes);
        if (!fault)
                return 1;
 
@@ -805,7 +762,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page)
        if (!remainder)
                return 1;
 
-       fault = check_bytes(end - remainder, POISON_INUSE, remainder);
+       fault = memchr_inv(end - remainder, POISON_INUSE, remainder);
        if (!fault)
                return 1;
        while (end > fault && end[-1] == POISON_INUSE)