2003-05-24 11:03:10

by Ren

[permalink] [raw]
Subject: [PATCH] SYSV fs: test in sysv_hash() is backwards

Hi all,

it seems sysvfs will compute a filename hash only in the case where
that name is too long.

After applying the patch below it will always update the hash, and
truncate too-long filenames beforehand. Also use full_name_hash() to
simplify the code.

Ren?



--- linux/fs/sysv/namei.c.orig 2003-05-24 12:49:57.000000000 +0200
+++ linux/fs/sysv/namei.c 2003-05-24 13:08:45.000000000 +0200
@@ -42,21 +42,11 @@

static int sysv_hash(struct dentry *dentry, struct qstr *qstr)
{
- unsigned long hash;
- int i;
- const unsigned char *name;
-
- i = SYSV_NAMELEN;
- if (i >= qstr->len)
- return 0;
/* Truncate the name in place, avoids having to define a compare
function. */
- qstr->len = i;
- name = qstr->name;
- hash = init_name_hash();
- while (i--)
- hash = partial_name_hash(*name++, hash);
- qstr->hash = end_name_hash(hash);
+ if (qstr->len > SYSV_NAMELEN)
+ qstr->len = SYSV_NAMELEN;
+ qstr->hash = full_name_hash(qstr->name, qstr->len);
return 0;
}


2003-05-24 11:37:01

by Ren

[permalink] [raw]
Subject: Re: [PATCH] SYSV fs: test in sysv_hash() is backwards

On Sat, 24 May 2003 13:32:13 +0200
Ren? Scharfe <[email protected]> wrote:

> it seems sysvfs will compute a filename hash only in the case where
> that name is too long.

... and that is just fine. On second glance, that is _exactly_ what
it should do. The common case is handled in fs/namei.c. D'oh!

There's opportunity for cleanup, though. Updated patch below.

Ren?



--- fs/sysv/namei.c.orig 2003-05-24 12:49:57.000000000 +0200
+++ fs/sysv/namei.c 2003-05-24 13:59:09.000000000 +0200
@@ -42,21 +42,12 @@

static int sysv_hash(struct dentry *dentry, struct qstr *qstr)
{
- unsigned long hash;
- int i;
- const unsigned char *name;
-
- i = SYSV_NAMELEN;
- if (i >= qstr->len)
- return 0;
/* Truncate the name in place, avoids having to define a compare
function. */
- qstr->len = i;
- name = qstr->name;
- hash = init_name_hash();
- while (i--)
- hash = partial_name_hash(*name++, hash);
- qstr->hash = end_name_hash(hash);
+ if (qstr->len > SYSV_NAMELEN) {
+ qstr->len = SYSV_NAMELEN;
+ qstr->hash = full_name_hash(qstr->name, qstr->len);
+ }
return 0;
}