home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.linux
- Path: sparky!uunet!mcsun!news.funet.fi!hydra!klaava!torvalds
- From: torvalds@klaava.Helsinki.FI (Linus Torvalds)
- Subject: Re: BUG of feature: cannot move `foo' accross file systems
- Message-ID: <1993Jan3.214155.25253@klaava.Helsinki.FI>
- Organization: University of Helsinki
- References: <1992Dec31.172305.1930@klaava.Helsinki.FI> <1993Jan1.141633.1724@victrola.sea.wa.us> <1993Jan3.205523.23937@klaava.Helsinki.FI>
- Date: Sun, 3 Jan 1993 21:41:55 GMT
- Lines: 64
-
- In article <1993Jan3.205523.23937@klaava.Helsinki.FI> kankkune@klaava.Helsinki.FI (Risto Kankkunen) writes:
- >>that's a feature, not a bug.
- >>many *nix'es don't allow that.
- >
- >OK, I can live with that, but is there any reason for this? I haven't
- >checked the sources (yet), but I think disallowing just requires extra
- >code with no benefits. Afterall, symlink is just a file containing the
- >path name of the file it points to.
-
- There is no good way to handle this in the kernel: moving files (even
- symbolic links) across filesystems is pretty much impossible to do
- cleanly as different fs's can have different filesystem semantics, and
- the kernel proper (or rather, the vfs layer) doesn't know about them
- (nor does it care - the idea with the vfs is exactly to allow different
- filesystems to have different opinions of what is going on).
-
- It's very easy to fake this on a user level: either in the 'rename()'
- library call or just in the 'mv' binary. The latter is probably the
- preferred way, if only because it serves for most people, while not
- cluttering up the library for other binaries (besides, handling the
- error cases might be ugly in the library, while 'mv' would know what to
- do).
-
- Naturally, any non-kernel solution (be it a library or mv change), is
- not guaranteed to be atomic, but with symbolic links this is probably
- not something you usually have to worry about. And a move across
- filesystems would be hard to make atomic even in the kernel, even if it
- was something I though was worth it. It's easy enough to fake with
- something like this:
-
- struct stat stat;
-
- if (lstat(oldname,&stat)) {
- perror("lstat");
- exit(1);
- }
- if (S_ISLINK(stat.st_mode)) {
- char buffer[1024];
-
- if (readlink(oldname,buffer,sizeof(buffer)) < 0) {
- perror("readlink");
- exit(1);
- }
- if (symlink(buffer, newfile)) {
- perror("symlink");
- exit(1);
- }
- if (unlink(oldname)) {
- perror("unlink");
- exit(1);
- }
- return 0;
- }
-
- Note that GNU mv already does something similar with regular files (ie
- it copies them across filesystems and then unlinks the original file if
- the copy was successfull), but symbolic links aren't the only thing mv
- won't touch. Directories, named pipes and any other special files share
- their non-movability with symlinks - understandable, as moving them can
- result in funny behavior (especially trying to move a directory by
- copying it and then removing it is so fraught with race-conditions that
- it's not really worth it).
-
- Linus
-