Subject: Re: mount_null: /mnt (/mnt) and /mnt are not distinct paths
To: Konrad Schroder <perseant@hitl.washington.edu>
From: Bill Sommerfeld <wes@thunk.epilogue.com>
List: tech-kern
Date: 06/30/1999 07:29:09
> --- mount_null.c	1999/06/25 19:28:37	1.6
> +++ mount_null.c	1999/06/29 18:20:17
> @@ -99,10 +99,6 @@
>  	if (realpath(argv[0], target) == 0)
>  		err(1, "%s", target);
>  
> -	if (subdir(target, argv[1]) || subdir(argv[1], target))
> -		errx(1, "%s (%s) and %s are not distinct paths",
> -		    argv[0], target, argv[1]);
> -
>  	args.target = target;
>  
>  	if (mount(MOUNT_NULL, argv[1], mntflags, &args))

One reason for this restriction is to avoid deadlocks.
(this limit really should be enforced by the kernel; now that we have
vn_isunder(), as a side effect of my sys___getcwd() implementation, it
can be..)

You need to impose an ordering between any pair of vnodes which may be
locked at the same time by the same process; the ordering used by
BSD4.4 VFS is that if Y is a vnode in a subdirectory of X, X must
always be locked before Y.

if you have:
	mount -t null /mnt  /mnt/xxx/yyy

Then, given the new pass-through locking scheme implemented by the
other Bill S., if two processes both try to look up /mnt/xxx/yyy, you
may deadlock:

	process A:
		lock /mnt
		lock /mnt/xxx
		unlock /mnt
		<blocks doing I/O reading the /mnt/xxx directory>

	process B:
		lock /mnt
		BLOCK waiting for lock on /mnt/xxx held by A

	process A:
		BLOCK waiting for lock on /mnt/xxx/yyy, AKA /mnt, held
			by B

						- Bill