diff options
author | Rasmus Villemoes <linux@rasmusvillemoes.dk> | 2014-12-05 23:41:33 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-01-09 15:51:08 -0800 |
commit | 72392ed0eb6fde96826cb9d66bd4f50a7ba61450 (patch) | |
tree | 488408d7485349d5df0b3f4cca74cda5e9be4518 /fs/kernfs/dir.c | |
parent | b7392d2247cfe6771f95d256374f1a8e6a6f48d6 (diff) | |
download | linux-72392ed0eb6fde96826cb9d66bd4f50a7ba61450.tar.gz linux-72392ed0eb6fde96826cb9d66bd4f50a7ba61450.tar.bz2 linux-72392ed0eb6fde96826cb9d66bd4f50a7ba61450.zip |
kernfs: Fix kernfs_name_compare
Returning a difference from a comparison functions is usually wrong
(see acbbe6fbb240 "kcmp: fix standard comparison bug" for the long
story). Here there is the additional twist that if the void pointers
ns and kn->ns happen to differ by a multiple of 2^32,
kernfs_name_compare returns 0, falsely reporting a match to the
caller.
Technically 'hash - kn->hash' is ok since the hashes are restricted to
31 bits, but it's better to avoid that subtlety.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/kernfs/dir.c')
-rw-r--r-- | fs/kernfs/dir.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 37989f02a226..2d881b381d2b 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -201,10 +201,14 @@ static unsigned int kernfs_name_hash(const char *name, const void *ns) static int kernfs_name_compare(unsigned int hash, const char *name, const void *ns, const struct kernfs_node *kn) { - if (hash != kn->hash) - return hash - kn->hash; - if (ns != kn->ns) - return ns - kn->ns; + if (hash < kn->hash) + return -1; + if (hash > kn->hash) + return 1; + if (ns < kn->ns) + return -1; + if (ns > kn->ns) + return 1; return strcmp(name, kn->name); } |