[LWN Logo]
Date:	Sun, 11 Jun 2000 15:35:02 -0400 (EDT)
From:	Alexander Viro <viro@math.psu.edu>
To:	I Lee Hetherington <ilh@sls.lcs.mit.edu>
Subject: Re: [BUG] Kernel 2.4.0-test1-ac10 changes open of symlink behavior.

On Sun, 11 Jun 2000, I Lee Hetherington wrote:

> Daniel Pittman wrote:
> > Now, at the point the open call is issued, '.gnus.el' is a symlink to a
> > non-existing file. I think, however, that the O_CREAT should cause it to
> > be created, yes?

Not. It's damn next to impossible to do without ugly races. And I mean the
kernel side - not just the userland. And yes, 2.2 _is_ racey. Moreover,
relying on creat(2) following dangling links is a very bad idea on any
system. Fix yer userland...

> Something changed.

<nods> It had been taken out and shot. Creation/removal _always_ applies
to the symlink, not to its target. For open() it means the following:

No O_CREATE, file doesn't exist => -ENOENT
No O_CREATE, file is a broken symlink => -ENOENT
No O_CREATE, file is a normal symlink => open the target
No O_CREATE, file exists => open the file

O_CREATE|O_EXCL, file doesn't exist => create
O_CREATE|O_EXCL, otherwise => -EEXIST

O_CREATE|O_NOFOLLOW, file doesn't exist => create
O_CREATE|O_NOFOLLOW, file is a symlink => -ELOOP
O_CREATE|O_NOFOLLOW, file exists => open the file

O_CREATE, file doesn't exist => create
O_CREATE, file is a broken symlink => -ENOENT
O_CREATE, file is normal symlink => open the target
O_CREATE, file exists => open the file 

Anybody who wants that back is very welcome to propose a working and
race-free implementation. IMNSHO such thing doesn't exist.

Again, the current rules are _very_ simple in respect to following links:
if we pass "foo/bar/baz" to a syscall that creates/removes/r objects
the _only_ directory entry that has a chance to be removed/added is "baz"
in directory refered to by foo/bar. Period.

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/