Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 288126
b: refs/heads/master
c: 200e9ef
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Mar 2, 2012
1 parent 8f8a6cc commit 489f781
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 19 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: 5707c87f20bca9e76969bb4096149de6ef74cbb9
refs/heads/master: 200e9ef7ab51f3dce4f35f90ea458cf43ea83bb8
52 changes: 34 additions & 18 deletions trunk/fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,25 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len)
return end_name_hash(hash);
}

/*
* We know there's a real path component here of at least
* one character.
*/
static inline unsigned long hash_name(const char *name, unsigned int *hashp)
{
unsigned long hash = init_name_hash();
unsigned long len = 0, c;

c = (unsigned char)*name;
do {
len++;
hash = partial_name_hash(c, hash);
c = (unsigned char)name[len];
} while (c && c != '/');
*hashp = end_name_hash(hash);
return len;
}

/*
* Name resolution.
* This is the basic name resolution function, turning a pathname into
Expand All @@ -1402,31 +1421,22 @@ static int link_path_walk(const char *name, struct nameidata *nd)

/* At this point we know we have a real path component. */
for(;;) {
unsigned long hash;
struct qstr this;
unsigned int c;
long len;
int type;

err = may_lookup(nd);
if (err)
break;

len = hash_name(name, &this.hash);
this.name = name;
c = *(const unsigned char *)name;

hash = init_name_hash();
do {
name++;
hash = partial_name_hash(c, hash);
c = *(const unsigned char *)name;
} while (c && (c != '/'));
this.len = name - (const char *) this.name;
this.hash = end_name_hash(hash);
this.len = len;

type = LAST_NORM;
if (this.name[0] == '.') switch (this.len) {
if (name[0] == '.') switch (len) {
case 2:
if (this.name[1] == '.') {
if (name[1] == '.') {
type = LAST_DOTDOT;
nd->flags |= LOOKUP_JUMPED;
}
Expand All @@ -1445,12 +1455,18 @@ static int link_path_walk(const char *name, struct nameidata *nd)
}
}

/* remove trailing slashes? */
if (!c)
if (!name[len])
goto last_component;
while (*++name == '/');
if (!*name)
/*
* If it wasn't NUL, we know it was '/'. Skip that
* slash, and continue until no more slashes.
*/
do {
len++;
} while (unlikely(name[len] == '/'));
if (!name[len])
goto last_component;
name += len;

err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW);
if (err < 0)
Expand Down

0 comments on commit 489f781

Please sign in to comment.