Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 272133
b: refs/heads/master
c: 7982482
h: refs/heads/master
i:
  272131: 5512767
v: v3
  • Loading branch information
Akinobu Mita authored and Linus Torvalds committed Nov 1, 2011
1 parent 43168b6 commit a0ea1a3
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 69 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 77311139f364d7f71fc9ba88f59fd90e60205007
refs/heads/master: 798248206b59acc6e1238c778281419c041891a7
1 change: 0 additions & 1 deletion trunk/fs/logfs/logfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,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);
Expand Down
22 changes: 0 additions & 22 deletions trunk/fs/logfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,28 +90,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.
*/
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
54 changes: 54 additions & 0 deletions trunk/lib/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 an unmatching character in an area of memory.
* @start: The memory area
* @c: Find a character other than c
* @bytes: 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);
47 changes: 2 additions & 45 deletions trunk/mm/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a0ea1a3

Please sign in to comment.