diff options
| author | Alexander Viro <viro@math.psu.edu> | 2002-03-01 21:30:13 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-03-01 21:30:13 -0800 |
| commit | 2dee55cd6c8eb5362b5c10616dc866f0342425ad (patch) | |
| tree | a6a2c1f2cfce753b57091863d1848f1262c87805 /fs/intermezzo | |
| parent | e145fcfa47b9073e1786a4d88e419463653fc7d5 (diff) | |
[PATCH] removal of LOOKUP_POSITIVE
LOOKUP_POSITIVE is not needed anymore. All callers of path_walk()
treat -ENOENT and negative dentry the same way. If you want a proof of
correctness - I'll send it, but it's a couple of pages of induction, basically
boiling down to "let's show that for any N we can replace the
if (lookup_flags & (LOOKUP_POSITIVE|LOOKUP_DIRECTORY))
break;
in link_path_walk() with
if ((lookup_flags & (LOOKUP_POSITIVE|LOOKUP_DIRECTORY)) ||
current->link_count <= N)
break;
without changing behaviour of the system". Pretty straightforward for
N = 0, then we look for places that can lead to call link_path_walk()
with current->link_count equal to N and show that if result of the test
changes, behaviour of callers doesn't. Since the depth of recursion is
limited, we had shown that test in question can be replaced with if (1).
And that's the only place in tree the ever checks for LOOKUP_POSITIVE.
The real reason behind that is very simple - indeed, suppose
we get a negative dentry out of path_walk(). What the hell could we
do with it? Its parent isn't locked, so both the name and parent can
change at any moment (could have changed already). There used to be
places that tried to play "let's get a negative dentry, lock its parent
and start doing something". All of them racy and all of them fixed
in 2.3. Fixed by switching to LOOKUP_PARENT...
Diffstat (limited to 'fs/intermezzo')
| -rw-r--r-- | fs/intermezzo/presto.c | 2 | ||||
| -rw-r--r-- | fs/intermezzo/vfs.c | 4 |
2 files changed, 3 insertions, 3 deletions
diff --git a/fs/intermezzo/presto.c b/fs/intermezzo/presto.c index 8c0d22467901..0b4ac7c97e2f 100644 --- a/fs/intermezzo/presto.c +++ b/fs/intermezzo/presto.c @@ -40,7 +40,7 @@ int presto_walk(const char *name, struct nameidata *nd) resolved pathname and not the symlink. SHP XXX: This code implies that direct symlinks do not work. SHP */ - unsigned int flags = LOOKUP_POSITIVE; + unsigned int flags = 0; ENTRY; err = 0; diff --git a/fs/intermezzo/vfs.c b/fs/intermezzo/vfs.c index 2af4d255852f..b632c8c92eeb 100644 --- a/fs/intermezzo/vfs.c +++ b/fs/intermezzo/vfs.c @@ -538,7 +538,7 @@ int lento_create(const char *name, int mode, struct lento_vfs_context *info) } /* this looks up the parent */ -// if (path_init(pathname, LOOKUP_FOLLOW | LOOKUP_POSITIVE, &nd)) +// if (path_init(pathname, LOOKUP_FOLLOW, &nd)) if (path_init(pathname, LOOKUP_PARENT, &nd)) error = path_walk(pathname, &nd); if (error) { @@ -687,7 +687,7 @@ int lento_link(const char * oldname, const char * newname, struct nameidata nd, old_nd; error = 0; - if (path_init(from, LOOKUP_POSITIVE, &old_nd)) + if (path_init(from, 0, &old_nd)) error = path_walk(from, &old_nd); if (error) goto exit; |
