From 6611bdac7c9d962482ec87d83f6f525785727d13 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Thu, 1 Sep 2005 01:50:27 +0000 Subject: [PATCH] Minor wording and grammar fixes. Approved by: murray --- .../articles/geom-class/article.sgml | 152 +++++++++--------- 1 file changed, 77 insertions(+), 75 deletions(-) diff --git a/en_US.ISO8859-1/articles/geom-class/article.sgml b/en_US.ISO8859-1/articles/geom-class/article.sgml index f39eb2dd80..7ffc67caf5 100644 --- a/en_US.ISO8859-1/articles/geom-class/article.sgml +++ b/en_US.ISO8859-1/articles/geom-class/article.sgml @@ -36,7 +36,7 @@ This text documents the way I created the gjournal facility, starting with learning how to do kernel - programming. It's assumed the reader is familiar with C + programming. It is assumed that the reader is familiar with C userland programming. @@ -50,8 +50,8 @@ Documentation - Documentation on kernel programming is scarce - it's one of - few areas where there's nearly nothing in the way of friendly + Documentation on kernel programming is scarce - it is one of + few areas where there is nearly nothing in the way of friendly tutorials, and the phrase use the source! really holds true. However, there are some bits and pieces (some of them seriously outdated) floating around that should be studied @@ -59,14 +59,14 @@ - The FreeBSD Developer's Handbook - part of the documentation - project, it doesn't contain anything specific to kernel-land + project, it does not contain anything specific to kernel-land programming, but rather some general information. - The FreeBSD Architecture Handbook - also from the documentation project, contains descriptions of several low-level facilities @@ -79,15 +79,17 @@ site - contains several interesting articles on kernel facilities. - The man pages in section 9 - most important - kernel-land calls are documented here. + The man pages in section 9 - for important + documentation on kernel functions. - The &man.geom.4; man page and PHK's GEOM slides + The &man.geom.4; man page and PHK's GEOM slides - for general introduction of the GEOM subsystem. - &man.style.9; man page, if the code should go to - FreeBSD CVS tree + The &man.style.9; man page - for documentation on + the coding-style conventions which must be followed for any code + which is to be committed to the FreeBSD CVS tree. @@ -97,18 +99,18 @@ Preliminaries - The best way to do kernel developing is to have (at least) + The best way to do kernel development is to have (at least) two separate computers. One of these would contain the development environment and sources, and the other would be used to test the newly written code by network-booting and network-mounting filesystems from the first one. This way if - the new code contains bugs and crashes the machine, it won't + the new code contains bugs and crashes the machine, it will not mess up the sources (and other live data). The - second system doesn't event have to have a proper display - it + second system does not even require a proper display. Instead, it could be connected with a serial cable or KVM to the first one. - But, since not everybody has two+ computers handy, there are + But, since not everybody has two or more computers handy, there are a few things that can be done to prepare an otherwise "live" system for developing kernel code. @@ -116,7 +118,7 @@ Converting a system for development For any kernel programming a kernel with - enabled is a must have. So enter + enabled is a must-have. So enter these in your kernel configuration file: options INVARIANT_SUPPORT @@ -129,7 +131,7 @@ With the usual way of installing the kernel (make installkernel) the debug kernel will not be - automatically installed. It's called + automatically installed. It is called kernel.debug and located in /usr/obj/usr/src/sys/KERNELNAME/. For convenience it should be copied to @@ -143,18 +145,18 @@ options DDB options KDB_TRACE - For this to work you might need to set a sysctl (if it's + For this to work you might need to set a sysctl (if it is not on by default): debug.debugger_on_panic=1 Kernel panics will happen, so care should be taken with the filesystem cache. In particular, having softupdates might - mean a latest file version could be lost if a panic occurs - before it's committed to storage. Disabling softupdates - yields a great performance hit (and it still doesn't guarantee - data consistency - mounting filesystem with the "sync" option - is needed for that) so for a compromise, the cache delays can + mean the latest file version could be lost if a panic occurs + before it is committed to storage. Disabling softupdates + yields a great performance hit, and still does not guarantee + data consistency. Mounting filesystem with the "sync" option + is needed for that. For a compromise, the cache delays can be shortened. There are three sysctl's that are useful for this (best to be set in /etc/sysctl.conf): @@ -168,11 +170,11 @@ For debugging kernel panics, kernel core dumps are required. Since a kernel panic might make filesystems unusable, this crash dump is first written to a raw - partition. Usually, this is the swap partition (it must be at - least as large as the physical RAM in the machine). On the - next boot (after filesystems are checked and mounted and - before swap is enabled), the dump is copied to a regular - file. This is controlled with two + partition. Usually, this is the swap partition. This partition must be at + least as large as the physical RAM in the machine. On the + next boot, the dump is copied to a regular file. + This happens after filesystems are checked and mounted, and + before swap is enabled. This is controlled with two /etc/rc.conf variables: dumpdev="/dev/ad0s4b" @@ -184,24 +186,24 @@ Writing kernel core dumps is slow and takes a long time so if you have lots of memory (>256M) and lots of panics it could - be frustrating to sit and wait while it's done (twice - first - to write it to swap, then to relocate it to filesystem). It's + be frustrating to sit and wait while it is done (twice - first + to write it to swap, then to relocate it to filesystem). It is convenient then to limit the amount of RAM the system will use via a /boot/loader.conf tunable: hw.physmem="256M" If the panics are frequent and filesystems large (or you - simply don't trust softupdates+background fsck) it's advisable + simply do not trust softupdates+background fsck) it is advisable to turn background fsck off via /etc/rc.conf variable: background_fsck="NO" This way, the filesystems will always get checked when - needed (with background fsck, a new panic could happen while - it's checking the disks). Again, the safest way is not to have - many local filesystems by using another computer as NFS + needed. Note that with background fsck, a new panic could happen while + it is checking the disks. Again, the safest way is not to have + many local filesystems by using another computer as an NFS server. @@ -210,20 +212,20 @@ For the purpose of making gjournal, a new empty subdirectory was created under an arbitrary user-accessible - directory. You don't have to create the module directory under + directory. You do not have to create the module directory under /usr/src. The Makefile - It's good practice to create + It is good practice to create Makefiles for every nontrivial coding project, which of course includes kernel modules. Creating the Makefile is simple thanks to extensive set of helper routines provided by the - system. In short, here's how it looks: + system. In short, here is how it looks: SRCS=g_journal.c KMOD=geom_journal @@ -259,9 +261,9 @@ sys/malloc.h headers must be included. - There's another mechanism for allocating memory, the UMA + There is another mechanism for allocating memory, the UMA (Universal Memory Allocator). See &man.uma.9; for details, but - it's a special type of allocator mainly used for speedy + it is a special type of allocator mainly used for speedy allocation of lists comprised of same-sized items (for example, dynamic arrays of structs). @@ -273,10 +275,10 @@ things needs to be maintained. Fortunately, this data structure is implemented (in several ways) by the C macros included in the system. The most used list type is TAILQ - because it's the most flexible. It's also the one with largest + because it is the most flexible. It is also the one with largest memory requirements (its elements are doubly-linked) and theoretically the slowest (though the speed variation is on - the order of several CPU instructions more, so it shouldn't be + the order of several CPU instructions more, so it should not be taken seriously). If data retrieval speed is very important, see @@ -295,8 +297,8 @@ The important thing here is that bios are dealt with asynchronously. That means that, in most parts of the code, - there's no analogue to userland's &man.read.2; and - &man.write.2; calls that don't return until a request is + there is no analogue to userland's &man.read.2; and + &man.write.2; calls that do not return until a request is done. Rather, a developer-supplied function is called as a notification when the request gets completed (or results in error). @@ -306,8 +308,8 @@ than the much more used imperative one (at least it takes a while to get used to it). In some cases helper routines g_write_data() and - g_read_data() can be used (NOT - ALWAYS!). + g_read_data() can be used, but NOT + ALWAYS!. @@ -320,7 +322,7 @@ If maximum performance is not needed, a much simpler way of making a data transformation is to implement it in userland - via the ggate (GEOM gate) facility. Unfortunately, there's no + via the ggate (GEOM gate) facility. Unfortunately, there is no easy way to convert between, or even share code between the two approaches. @@ -329,7 +331,7 @@ GEOM class GEOM class has several "class methods" that get called - when there's no geom instance available (or they're simply not + when there is no geom instance available (or they are simply not bound to a single instance): @@ -372,11 +374,11 @@ The name softc is a legacy term for driver private data. The name most probably - comes from archaic term software control block. - In GEOM, it's a structure (more precise: pointer to a + comes from the archaic term software control block. + In GEOM, it is a structure (more precise: pointer to a structure) that can be attached to a geom instance to hold whatever data is private to the geom instance. In gjournal - (and most of the other GEOM classes), some of it's members + (and most of the other GEOM classes), some of its members are: @@ -387,7 +389,7 @@ consumer this geom consumes struct g_consumer **disks : Array - of struct g_consumer*. (It's not possible + of struct g_consumer*. (It is not possible to use just single indirection because struct g_consumer* are created on our behalf by GEOM). @@ -412,14 +414,14 @@ - It's assumed that geom classes know how to handle metadata + It is assumed that geom classes know how to handle metadata with version ID's lower than theirs. Metadata is located in the last sector of the provider (and thus must fit in it). (All this is implementation-dependent but all existing - code works like that, and it's supported by libraries.) + code works like that, and it is supported by libraries.) @@ -429,10 +431,10 @@ - user calls &man.geom.8; utility (or one of it's + user calls &man.geom.8; utility (or one of its hardlinked friends) - the utility figures out which geom class it's + the utility figures out which geom class it is supposed to handle and searches for geom_CLASSNAME.so library (usually in @@ -450,10 +452,10 @@ &man.geom.8; looks in the command-line definition - for the command (usually "label"), calls a helper + for the command (usually "label"), and calls a helper function. - helper function checks parameters & gathers + helper function checks parameters and gathers metadata, which it proceeds to write to all concerned providers. @@ -465,7 +467,7 @@ (The above sequence of events is implementation-dependent - but all existing code works like that, and it's supported by + but all existing code works like that, and it is supported by libraries.) @@ -532,10 +534,10 @@ .spoiled : called when some underlying provider gets written to - .start : handles IO + .start : handles I/O - These functions are called from g_down? kernel thread and + These functions are called from the g_down? kernel thread and there can be no sleeping in this context (no blocking on a mutex or any kind of locks) which limits what can be done quite a bit, but forces the handling to be fast. @@ -567,16 +569,16 @@ When a user process issues read data X at offset Y - of a file request, this is what happenes: + of a file request, this is what happens: - The filesystem converts the request into struct bio - instance and passes it to GEOM subsystem. It knows what geom + The filesystem converts the request into a struct bio + instance and passes it to the GEOM subsystem. It knows what geom instance should handle it because filesystems are hosted directly on a geom instance. - The request ends up as a call to + The request ends up as a call to the .start() function made on the g_down thread and reaches the top-level geom instance. @@ -612,12 +614,12 @@ See &man.g.bio.9; man page for information how the data is passed back and forth in the bio - structure (note particular the bio_parent + structure (note in particular the bio_parent and bio_children fields and how they are handled). - One important feature is: THERE CAN BE NO SLEEPING IN G_UP - AND G_DOWN THREADS. This means that none of the following + One important feature is: THERE CAN BE NO SLEEPING IN G_UP + AND G_DOWN THREADS. This means that none of the following things can be done in those threads (the list is of course not complete, but only informative): @@ -637,11 +639,11 @@ sx locks - This restriction is here to stop geom code clogging the IO + This restriction is here to stop geom code clogging the I/O request path, because sleeping in the code is usually not time-bound and there can be no guarantiees on how long will it take (there are some other, more technical reasons also). It - also means that there's not much that can be done in those + also means that there is not much that can be done in those threads; for example, almost any complex thing requires memory allocation. Fortunately, there is a way out: creating additional kernel threads. @@ -652,20 +654,20 @@ Kernel threads are created with &man.kthread.create.9; function, and they are sort of similar to userland threads in - behaviour, only they can't return to caller to signify + behaviour, only they cannot return to caller to signify termination, but must call &man.kthread.exit.9;. In geom code, the usual use of threads is to offload processing of requests from g_down thread (the .start() function). These threads look like event handlers: they have a linked - list of event associated with them (on which events can posted + list of event associated with them (on which events can be posted by various functions in various threads so it must be protected by a mutex), take the events from the list one by one and process them in a big switch() statement. - The main benefit of using a thread to handle IO requests + The main benefit of using a thread to handle I/O requests is that it can sleep when needed. Now, this sounds good, but should be carefully thought out. Sleeping is well and very convenient but can very effectively destroy performance of the @@ -683,11 +685,11 @@ Mutexes in FreeBSD kernel (see &man.mutex.9; man page) have one distinction from their more common userland cousins - they - disallow sleeping (meaning: the code can't sleep while holding + disallow sleeping (meaning: the code cannot sleep while holding a mutex). If the code needs to sleep a lot, &man.sx.9; locks - may be more appropriate. (On the other hand, if you do almost + may be more appropriate. On the other hand, if you do almost everything in a single thread, you may get away with no - mutexes at all). + mutexes at all.