Subject: Re: Possible VOP_LOOKUP() interface change
To: Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us>
From: Bill Studenmund <wrstuden@nas.nasa.gov>
List: tech-kern
Date: 09/07/1999 13:13:51
On Tue, 7 Sep 1999, Bill Sommerfeld wrote:

> As long as VOP_LOOKUP can still *look at* the ISLASTCN bit, portalfs
> can be made to work (by creating intermediate vnodes accumulating the
> pathname bits one at a time..)

There's another way... The thing I don't like about this is it'll be slow
- we'll be itterating a lot on portal_lookup() to make all these nodes
when we don't have to - and no one's volinteered to make this change. :-)

> I think the proposed change is worthwhile and should be made.

I should note that I'm not that opposed to the changes Charles proposed
(making all but the last lookup be LOOKUP with the *PARENT bits cleared).
I think we can do it another way, but that's fine.

I am opposed to the idea of breaking portalfs along the way. :-)

But there's another way to fix portalfs, even within the terms of what
Charles proposed. Basically lookup() will now have to fix up a few more
things when portalfs (or any other fs) decides the component it was fed
was the last one. 

Assuming we don't remove the ability for a LOOKUP routine to gobble up
more components (which while Charles hates how we do it now, he's not said
he wants to rip it out now AFAICT), all we need to do is change lookup()
in the section where it notices that all of the path has been consumed. 

With the proposed lookup() change, at this point, we'll have a reference
to the parent dir (dp) and to the new node (ndp->ni_vp). vdp will be
locked and pdp unlocked. Now all we do is assert ISLASTCN, assuming the
LOOKUP routine did the right thing. Now we'll need to fix up the locking
too.  Something like

		if (ndp->ni_next[0] == '\0') {
			/* the LOOKUP routine ate the whole path */
			cnp->cn_flags |= ISLASTCN;
			if ((dp != ndp->ni_vp) && (real_flags & LOCKPARENT) {
				/* re-lock parent */
				struct vnode *vp = ndp->ni_vp;
				dpunlocked = 0;
				if (cnp->cn_flags & ISDOTDOT) {
					error = vn_lock(dp, LK_EXCLUSIVE)))
				} else {
					VOP_UNLOCK(vp, 0);
					if ((error = vn_lock(dp,
							LK_EXCLUSIVE))) {
						dpunlocked = 1;
					} else 
						error = vn_lock(vp,
								LK_EXCLUSIVE);
				}
				if (error) {
					vrele(vp);
					goto bad;
				}
			}
		}

or something like that.

With this change, portalfs should keep working even if we don't show it
*PARENT.

Thoughts?

Take care,

Bill