Re: Linux-2.2.2-pre2..

Linus Torvalds (torvalds@transmeta.com)
Sat, 6 Feb 1999 23:17:26 -0800 (PST)


On Sun, 7 Feb 1999, Alexander Viro wrote:
>
> Could you elaborate? I'ld see the point if we would split the *method*,
> but I don't see the reason for splitting the VFS-level code. Method has to
> distingush between directory/non-directory move anyway - '..' flipping and
> emptiness check are fs-specific. Ditto for nlink overflow checking (BTW,
> it asks for additional field in struct super, IMHO. Say it, s_max_nlink).

Basically, splitting the method is what we should do for 2.3.x, but it's
just not feasible for 2.2.x at this stage.

But that's why I want the VFS layer split - so that when we _do_ split the
method, the VFS layer is all ready for it. Because basically a directory
rename _is_ very different from a normal file rename.

> BTW, we'll have to redo it in 2.3 - serialization is way too rough right
> now and we can easily make if finer if we'll use d_flags to mark source of
> rename() in progress

No, you can't just mark the rename in process - if you really want to
split up the per-fs rename semaphore into finer-grained setups so that you
can do multiple directory moves concurrently, then you have to poison not
just the source, you have to poison the whole path down from the source
down to the root of the filesystem.

> (if there are no marked points on the path from
> target to the closest common ancestor of target and source we can go ahead
> without waiting for other renames).

Right, but the only sane way of detecting this is to poison down to the
root, and if you hit another process' poison bit you'd roll back and wait
with the rename.

HOWEVER - I don't actually think it makes much sense to try to aim for
tons of concurrency in directory renaming. It's not as if it is a very
common operation anyway, so the per-fs lock works wonderfully well (and
doesn't impact any other operations).

> ObRaces: assume that /foo/bar/a and /foo/bar/b are both symlinks to "..".
> Now, unlink("/foo/bar/a/bar/b") and unlink("/foo/bar/b/bar/a") shouldn't
> *both* succeed, right?

Why not? How you got to the point is meaningless. You don't unlink a
_path_, you unlink the last entry it points to.

Basically, if you have senseless users, there's _no_ point in the kernel
trying to second-guess what they mean. You'll get it wrong anyway, and
you'll add a lot of complexity trying to get it right.

Basic rule: make it as complex as you have to, but no more.

Linus

-
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/