Subject: Re: curproc removal (NFS, ...)
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Jonathan Stone <jonathan@dsg.stanford.edu>
List: tech-kern
Date: 05/25/2004 12:27:22
In message <1085467157.743699.427.nullmailer@yamt.dyndns.org>YAMAMOTO Takashi write


>i understand why you want to eliminate curproc.
>but i don't understand why you want to eliminate (struct proc *)NULL
>and (ab)use uio_procp.

Ah. OK, now I see what you mean. Thank you (again) for clarifying.


I had acutally suggested passing an explicit struct proc * to
soreceive.  Matt Thomas pointed out that one could just use the
uio->uio_procp, and argued that was ``cleaner''.  I may misremember
Matt's opinion, but what I recall was along the lines of: the
uio->uio_procp is already there, and (implicitly) if we pass another
struct proc *, they might end up both non-NULL, and different. Yuck.

I thought the only places I did that are where the caller already
passes a non-NULL sruct mbuf **mp to soreceive, in which case the
comment in soreceive() applies:

/*
 * The caller may receive the data as a single mbuf chain by supplying
 * an mbuf **mp0 for use in returning the chain.  The uio is then used
 * only for the count in uio_resid.
 */

But now the comment is out of date; the code also usese uio->uio_procp. Why?

The real motivation for abusing that (or to pass an explicit struct
proc *) is that soreceive() can call the per-domain dom_externalize
method. For Unix-domain sockets, that's unp_externalize(), which used
to grab curproc (which we agree is bad), but now gets the struct proc
* passed to soreceive() via uio->uio_procp. (I could easily have
passed in an explicit struct proc * instead; but see above).


The bottom line is that if you want to do arbitrary operations on
Unix-domain sockets, you basically *have* to keep track of some struct
proc * ``associated'' with that Unix-domain socket, wtih approrpriate
permissions to frob the filesystem state associated with the socket;
and you must pass that into sosend() or (implicitly) into soreceive().

Remember the whole idea of calling sosend() and soreceive() outside of
the ``top half'' is currently not well-defined. And if you are calling
from the `top half', the process to pass down is obviously the current
process, and not arbitrary.

I know what *I* would mandate, if I could. I'd prefer to allow a NULL
struct proc * for sosend() or soreceive() for data-only transfer on
connected sockets.  Unfortunately, the p->p_stats->p_ru.ru_msgrcv
acounting and the p->p_rlimit[RLIMIT_SBSIZE make what I have done in
the past, and what I'd prefer to mandate ... tricky.

I could at least write a manpage about what I *want* to permit.
But what should it be called?

>> So you can't really tell, at the socket layer, what might or might not be
>> done with the struct proc * argument.
>
>do you mean, because proc pointer isn't used at all or is used in the
>very protocol specific manner, a pointer to an arbitrary proc is good enough?

I suspect we're talking at cross-purposes with that word `arbitrary'.
The struct proc * being passed must be NULL (if that works) or the
`owner', in some sense, of the request being passed.  (Resource
accounting gets charged to that process; any VFS operations for
PF_UNIX sockets will [or should] use it; and so on).

Time to write that manpage, I guess.