Subject: Re: hardlink to symlink
To: Hubert Feyrer <hubert.feyrer@rz.uni-regensburg.de>
From: Bill Studenmund <wrstuden@nas.nasa.gov>
List: tech-kern
Date: 05/12/1999 11:08:46
Checking through old mail, and found this.
On Fri, 9 Apr 1999, Hubert Feyrer wrote:
>
> Hi,
>
> I've used hardlinks to symlinks under Solaris, and understanding
> hardlinks as "just another directory entry" for whatever object
> (referenced by i/vnode), was wondering why NetBSD didn't support
> this.
Do standards have anything to say?
> Example:
> $ ln -s /etc/passwd symlink
> $ ln symlink hardlink
> ln: hardlink: Cross-device link
>
>
> It seems this has two causes:
> 1. the kernel tried to follow the symlink which caused it to abort
> if the target of the symlink was on a different filesystem.
>
> If the link points to a (valid) file on the same filesystem,
> traversal of the link will result in a hardlink to the target
> file, which may not be what's intended.
>
> These two cases can be caught by not traversing the symlink.
>
> 2. the ln(1) command failed if the symlink didn't point to a valid
> file. Again, not traversing the link here solves this.
>
> The patches below fix these two errors:
>
> $ ln symlink hardlink
> $ ls -lai hardlink symlink
> 368953 lrwxr-xr-x 2 feyrer wheel 11 Apr 9 05:52 hardlink -> /etc/passwd
> 368953 lrwxr-xr-x 2 feyrer wheel 11 Apr 9 05:52 symlink -> /etc/passwd
>
> I'm not a kernel hacker so I would appreciate any inputs on this.
> Else I'll be happy to commit this.
Except that you commented out the old code rather than deleting it, I
think they look great!
Take care,
Bill
> Index: bin/ln/ln.c
> ===================================================================
> RCS file: /cvsroot/src/bin/ln/ln.c,v
> retrieving revision 1.15
> diff -u -r1.15 ln.c
> --- ln.c 1998/07/28 05:31:25 1.15
> +++ ln.c 1999/04/09 03:42:09
> @@ -137,7 +137,8 @@
>
> if (!sflag) {
> /* If target doesn't exist, quit now. */
> - if (stat(target, &sb)) {
> + /* if (stat(target, &sb)) { */ /*HF*/
> + if (lstat(target, &sb)) {
> warn("%s", target);
> return (1);
> }
> Index: sys/kern/vfs_syscalls.c
> ===================================================================
> RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
> retrieving revision 1.133
> diff -u -r1.133 vfs_syscalls.c
> --- vfs_syscalls.c 1999/03/31 19:18:45 1.133
> +++ vfs_syscalls.c 1999/04/09 03:42:13
> @@ -1116,7 +1116,9 @@
> struct nameidata nd;
> int error;
>
> - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
> +
> + /*HF*//* NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); */
> + NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
> if ((error = namei(&nd)) != 0)
> return (error);
> vp = nd.ni_vp;
>
> --
> Hubert Feyrer <hubert.feyrer@rz.uni-regensburg.de>
>
>
>