aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-06 16:54:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-06 16:54:56 -0400
commitf68e556e23d1a4176b563bcb25d8baf2c5313f91 (patch)
tree4c43c375dd0c608ed506953d80ebfedacca37161 /fs/namei.c
parent23f347ef63aa36b5a001b6791f657cd0e2a04de3 (diff)
Make the "word-at-a-time" helper functions more commonly usable
I have a new optimized x86 "strncpy_from_user()" that will use these same helper functions for all the same reasons the name lookup code uses them. This is preparation for that. This moves them into an architecture-specific header file. It's architecture-specific for two reasons: - some of the functions are likely to want architecture-specific implementations. Even if the current code happens to be "generic" in the sense that it should work on any little-endian machine, it's likely that the "multiply by a big constant and shift" implementation is less than optimal for an architecture that has a guaranteed fast bit count instruction, for example. - I expect that if architectures like sparc want to start playing around with this, we'll need to abstract out a few more details (in particular the actual unaligned accesses). So we're likely to have more architecture-specific stuff if non-x86 architectures start using this. (and if it turns out that non-x86 architectures don't start using this, then having it in an architecture-specific header is still the right thing to do, of course) Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c35
1 files changed, 3 insertions, 32 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 1898198abc3d..0062dd17eb55 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1407,18 +1407,9 @@ static inline int can_lookup(struct inode *inode)
1407 */ 1407 */
1408#ifdef CONFIG_DCACHE_WORD_ACCESS 1408#ifdef CONFIG_DCACHE_WORD_ACCESS
1409 1409
1410#ifdef CONFIG_64BIT 1410#include <asm/word-at-a-time.h>
1411 1411
1412/* 1412#ifdef CONFIG_64BIT
1413 * Jan Achrenius on G+: microoptimized version of
1414 * the simpler "(mask & ONEBYTES) * ONEBYTES >> 56"
1415 * that works for the bytemasks without having to
1416 * mask them first.
1417 */
1418static inline long count_masked_bytes(unsigned long mask)
1419{
1420 return mask*0x0001020304050608ul >> 56;
1421}
1422 1413
1423static inline unsigned int fold_hash(unsigned long hash) 1414static inline unsigned int fold_hash(unsigned long hash)
1424{ 1415{
@@ -1428,15 +1419,6 @@ static inline unsigned int fold_hash(unsigned long hash)
1428 1419
1429#else /* 32-bit case */ 1420#else /* 32-bit case */
1430 1421
1431/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
1432static inline long count_masked_bytes(long mask)
1433{
1434 /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
1435 long a = (0x0ff0001+mask) >> 23;
1436 /* Fix the 1 for 00 case */
1437 return a & mask;
1438}
1439
1440#define fold_hash(x) (x) 1422#define fold_hash(x) (x)
1441 1423
1442#endif 1424#endif
@@ -1464,17 +1446,6 @@ done:
1464} 1446}
1465EXPORT_SYMBOL(full_name_hash); 1447EXPORT_SYMBOL(full_name_hash);
1466 1448
1467#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
1468#define ONEBYTES REPEAT_BYTE(0x01)
1469#define SLASHBYTES REPEAT_BYTE('/')
1470#define HIGHBITS REPEAT_BYTE(0x80)
1471
1472/* Return the high bit set in the first byte that is a zero */
1473static inline unsigned long has_zero(unsigned long a)
1474{
1475 return ((a - ONEBYTES) & ~a) & HIGHBITS;
1476}
1477
1478/* 1449/*
1479 * Calculate the length and hash of the path component, and 1450 * Calculate the length and hash of the path component, and
1480 * return the length of the component; 1451 * return the length of the component;
@@ -1490,7 +1461,7 @@ static inline unsigned long hash_name(const char *name, unsigned int *hashp)
1490 len += sizeof(unsigned long); 1461 len += sizeof(unsigned long);
1491 a = *(unsigned long *)(name+len); 1462 a = *(unsigned long *)(name+len);
1492 /* Do we have any NUL or '/' bytes in this word? */ 1463 /* Do we have any NUL or '/' bytes in this word? */
1493 mask = has_zero(a) | has_zero(a ^ SLASHBYTES); 1464 mask = has_zero(a) | has_zero(a ^ REPEAT_BYTE('/'));
1494 } while (!mask); 1465 } while (!mask);
1495 1466
1496 /* The mask *below* the first high bit set */ 1467 /* The mask *below* the first high bit set */