$FreeBSD: head/sys/geom/notes 110523 2003-02-07 23:08:24Z phk $ For the lack of a better place to put them, this file will contain notes on some of the more intricate details of geom. ----------------------------------------------------------------------- Locking of bio_children and bio_inbed bio_children is used by g_std_done() and g_clone_bio() to keep track of children cloned off a request. g_clone_bio will increment the bio_children counter for each time it is called and g_std_done will increment bio_inbed for every call, and if the two counters are equal, call g_io_deliver() on the parent bio. The general assumption is that g_clone_bio() is called only in the g_down thread, and g_std_done() only in the g_up thread and therefore the two fields do not generally need locking. These restrictions are not enforced by the code, but only with great care should they be violated. It is the responsibility of the class implementation to avoid the following race condition: A class intend to split a bio in two children. It clones the bio, and requests I/O on the child. This I/O operation completes before the second child is cloned and g_std_done() sees the counters both equal 1 and finishes off the bio. There is no race present in the common case where the bio is split in multiple parts in the class start method and the I/O is requested on another GEOM class below: There is only one g_down thread and the class below will not get its start method run until we return from our start method, and consequently the I/O cannot complete prematurely. In all other cases, this race needs to be mitigated, for instance by cloning all children before I/O is request on any of them. Notice that cloning an "extra" child and calling g_std_done() on it directly opens another race since the assumption is that g_std_done() only is called in the g_up thread.