Subject: Re: New patch (Re: RFC: addition of B_NESTED to buf.h and vfs_bio.c)
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Reinoud Zandijk <reinoud@netbsd.org>
List: tech-kern
Date: 01/07/2006 16:05:12
--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi Takashi,

On Sat, Jan 07, 2006 at 12:41:53PM +0900, YAMAMOTO Takashi wrote:
> > Basicly, i've tried to make the nested buffers interface agnostic as much 
> > as possible and indifferent to other layers they can be passed to. The 
> > buffers can even be brelse()'d or issued with B_ASYNC without a callback; 
> > the code will do the right thing. If code uses callbacks they can just 
> > brelse() them like it is a normal buffer; no need for special knowledge. 
> > This is documented in the source. A patch for manpages is not added yet.
> 
> using brelse() for non-buffercache buffers is a bug.

maybe in `the new world order' of iobufs and buffercache bufs?

Its basicly a fundemental problem. When a buffer (regardless of what kind) 
is processed, a biodone() is issued on the buffer. If a B_CALL is 
specified, the callback is issued and the callback is responsable for the 
cleaning up and - due to the hack in biodone() for the origional pager - 
the callback has to clean up and has to know if it was a normal buffer or 
an iobuffer.

The best solution would be to break this callback hack in that the call 
back is issued when requested and then the normal processing and optional 
cleanup in biodone() is done as origionally intended by the design. (see 
source code for the comment on this) relieving the callback of its cleaning 
up burden.

If i pass a nested buffer to say a device with a B_ASYNC flag this device 
calls biodone() on it and as long as it doesn't call brelse() all ought to 
go OK. Since this is normally considered `not-done` it is OK.

For now, I could let biodone() clean up the nested iobuffer itself but 
wouldn't that break the semantics that biodone() leaves a buffer alive if 
B_ASYNC is *not* specified? Or should all the nested buffers kept alive 
(unless the callback explicitly removes them offcource) until the master 
buffer is biodone()'d eventually?

Would a nested buffer cleanup in `putiobuf' satisfy you? (and removal of 
the addition to the brelse code), Then biodone() can decide to either call 
brelse() or putiobuf().

> i don't understand what exactly you want to achieve.  can you explain?
> to me, it seems that you are going to increase the sizeof(struct buf)
> without any benefits.

The main benefit to nesting is that an action on an (io)buf can be split up 
into several independently sheduled actions on the nested buf's like 
genfs's getpages/putpages do whatever the reason is. Genfs only uses a 
hardcoded mechanism to skip over dirty pages and the nested buffer 
implementation is a generalisation of this mechanism.

By implementing it this way this splitting up is streamlined and reusable 
and provides another set of b_private, b_bp, b_call and other 
flags/values/callbacks that can be reused by the code that decided to split 
up the buffer.

with regards,
Reinoud


--UlVJffcvxoiEqYs2
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (NetBSD)

iQEVAwUBQ7/YoYKcNwBDyKpoAQLAgAf/VXSesqOqqxXh3Sydy28ayamD+PACpdqL
42ztxtzrdAWFyyOKLmOuP5cL3AbxYrWYDnbIATX7vw2EH+J510vFFzZ4WnwPOVDm
VSBza5VmcSPNR8TEeADylGiB5HsSWFx5T3Y7pHskNtfigIBIOaAJbonmsPB/axBk
GEV51F2IBQ1uWATQUE0DYpDPhrJcaHls8JoFwHZaMiLpylXMeZGuMBy6hJllOfFl
Jtk92wyT4HiRlwbmNW41ilL49vCpKuxnqFn8Dd3kAzhvJ/SDhwgmwpeUDogbcGwq
Ia1M5/R1BgqMRS8uckzx5m4pgTcS+YWsHDG2SzgxDNjWX0QYLItGkg==
=zh5U
-----END PGP SIGNATURE-----

--UlVJffcvxoiEqYs2--