
Add and update documentation to the new commit procedure.



---

 cur-root/README          |   10 
 cur-root/doc/guide.lyx   |  626 +++++++++++++++++++++++++++++++++++++++++++++++
 cur-root/doc/guide.txt   |  295 ++++++++++++++++++++++
 cur-root/doc/libjio.3    |  101 +++----
 cur-root/doc/libjio.lyx  |   47 +--
 cur-root/doc/libjio.txt  |   82 ++----
 cur/doc/big_transactions |    9 
 cur/doc/jiofsck          |   12 
 cur/doc/threads          |   20 -
 9 files changed, 1038 insertions(+), 164 deletions(-)

diff -puN /dev/null doc/guide.lyx
--- /dev/null	2004-04-13 23:59:22.000000000 -0300
+++ cur-root/doc/guide.lyx	2004-06-19 23:57:46.000000000 -0300
@@ -0,0 +1,626 @@
+#LyX 1.3 created this file. For more info see http://www.lyx.org/
+\lyxformat 221
+\textclass article
+\language english
+\inputencoding auto
+\fontscheme default
+\graphics default
+\paperfontsize default
+\papersize Default
+\paperpackage a4
+\use_geometry 0
+\use_amsmath 0
+\use_natbib 0
+\use_numerical_citations 0
+\paperorientation portrait
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\defskip medskip
+\quotes_language english
+\quotes_times 2
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+
+\layout Title
+
+libjio Programmer's Guide
+\layout Author
+
+Alberto Bertogli (albertogli@telpin.com.ar)
+\layout Standard
+
+
+\begin_inset LatexCommand \tableofcontents{}
+
+\end_inset 
+
+
+\layout Section
+
+Introduction
+\layout Standard
+
+This small document attempts serve as a guide to the programmer who wants
+ to make use of the library.
+ It's not a replacement for the man page or reading the code; but it's a
+ good starting point for everyone who wants to get involved with it.
+\layout Standard
+
+The library is not complex to use at all, and the interfaces were designed
+ to be as intuitive as possible, so the text is structured as a guide to
+ present the reader all the common structures and functions the way they're
+ normally used.
+\layout Section
+
+Definitions
+\layout Standard
+
+This is a library which provides a journaled transaction-oriented I/O API.
+ You've probably read this a hundred times already in the documents, and
+ if you haven't wondered yet what on earth does this mean you should be
+ reading something else!
+\layout Standard
+
+We say this is a transaction-oriented API because we make transactions the
+ center of our operations, and journaled because we use a journal (which
+ takes the form of a directory with files on it) to guarantee coherency
+ even after a crash at any point.
+\layout Standard
+
+Here we think a transaction as a list of 
+\emph on 
+(buffer, length, offset)
+\emph default 
+ to be applied to a file.
+ That triple is called an 
+\emph on 
+operation
+\emph default 
+, so we can say that a transaction represent an ordered group of operations
+ on the same file
+\emph on 
+.
+\layout Standard
+
+The act of 
+\emph on 
+committing
+\emph default 
+ a transaction means writing all the elements of the list; and 
+\emph on 
+rollbacking
+\emph default 
+ means to undo a previous commit, and leave the data just as it was before
+ doing the commit.
+\begin_inset Foot
+collapsed false
+
+\layout Standard
+
+While all this definitions may seem obvious to some people, it requires
+ special attention because there are a lot of different definitions, and
+ it's not that common to see 
+\begin_inset Quotes eld
+\end_inset 
+
+transaction
+\begin_inset Quotes erd
+\end_inset 
+
+ applied to file I/O (it's a term used mostly on database stuff), so it's
+ important to clarify before continuing.
+\end_inset 
+
+
+\layout Standard
+
+It's important to note that the library not only provides a convenient and
+ easy API to perform this kind of operations, but provides a lot of guarantees
+ while doing this.
+ The most relevant and useful is that at any point of time, even if we crash
+ horribly, a transaction will be either fully applied or not applied at
+ all.
+ You should not ever see partial transactions or any kind of data corruption.
+\layout Standard
+
+To achieve this, the library uses what is called a 
+\emph on 
+journal
+\emph default 
+, a very vague (and fashionable) term we use to describe a set of auxiliary
+ files that get created to store temporary data at several stages.
+ The proper definition and how we use them is outside the scope of this
+ document, and you as a programmer shouldn't need to deal with it.
+ In case you're curious, it's described in a bit more detail in another
+ text which talks about how the library works internally.
+ Now let's get real.
+\layout Section
+
+The data types
+\layout Standard
+
+To understand any library, it's essential to be confident in the knowledge
+ of their data structures and how they relate each other.
+ In libjio we have two basic structures which have a very strong relationship,
+ and represent the essential objects we deal with.
+ Note that you normally don't manipulate them directly, because they have
+ their own initializer functions, but they are the building blocks for the
+ rest of the text, which, once this is understood, is obvious and self-evident.
+\layout Standard
+
+The first structure we face is 
+\family typewriter 
+struct\SpecialChar ~
+jfs
+\family default 
+, called the 
+\emph on 
+file structure
+\emph default 
+, and it represents an open file, just like a regular file descriptor or
+ a 
+\family typewriter 
+FILE\SpecialChar ~
+*
+\family default 
+.
+\layout Standard
+
+Then you find 
+\family typewriter 
+struct\SpecialChar ~
+jtrans
+\family default 
+, called the 
+\emph on 
+transaction structure
+\emph default 
+, which represents a single transaction.
+ You can have as many transactions as you want, and operate on all of them
+ simultaneously without problems; the library is entirely thread safe so
+ there's no need to worry about that.
+\layout Section
+
+The basic functions
+\layout Standard
+
+Now that we've described our data types, let's see how we can really operate
+ with the library.
+ 
+\layout Standard
+
+First of all, as with regular I/O, you need to open your files.
+ This is done with 
+\family typewriter 
+jopen()
+\family default 
+, which looks a lot like 
+\family typewriter 
+open()
+\family default 
+ but takes a file structure instead of a file descriptor (this will be very
+ common among all the functions), and adds a new parameter 
+\emph on 
+jflags
+\emph default 
+ that can be used to modify some subtle library behaviour we'll see later,
+ and it's normally not used.
+\layout Standard
+
+We have a happy file structure open now, and the next thing to do would
+ be to create a transaction.
+ This is what 
+\family typewriter 
+jtrans_init()
+\family default 
+ is for: it takes a file structure and a transaction structure and initializes
+ the latter, leaving it ready to use.
+\layout Standard
+
+So we have our transaction, let's add a write operation to it; to do this
+ we use 
+\family typewriter 
+jtrans_add()
+\family default 
+.
+ We could keep on adding operations to the transaction by keep on calling
+ 
+\family typewriter 
+jtrans_add()
+\family default 
+ as many times as we want.
+\layout Standard
+
+Finally, we decide to apply our transaction to the file, that is, write
+ all the operations we've added.
+ And this is the easiest part: we call 
+\family typewriter 
+jtrans_commit()
+\family default 
+, and that's it!
+\layout Standard
+
+When we're done using the file, we call 
+\family typewriter 
+jclose()
+\family default 
+, just like we call 
+\family typewriter 
+close()
+\family default 
+.
+\layout Standard
+
+Let's put it all together and code a nice 
+\begin_inset Quotes eld
+\end_inset 
+
+hello world
+\begin_inset Quotes erd
+\end_inset 
+
+ program (return values are ignored for simplicity):
+\layout LyX-Code
+
+char buf[] = "Hello world!";
+\layout LyX-Code
+
+struct jfs file;
+\layout LyX-Code
+
+struct jtrans trans;
+\newline 
+
+\newline 
+
+\layout LyX-Code
+
+jopen(&file, "filename", O_RDWR | O_CREAT, 0600, 0);
+\layout LyX-Code
+
+jtrans_init(&file, &trans);
+\newline 
+
+\newline 
+
+\layout LyX-Code
+
+jtrans_add(&trans, buf, strlen(buf), 0);
+\newline 
+
+\newline 
+
+\layout LyX-Code
+
+jtrans_commit(&trans);
+\newline 
+
+\newline 
+
+\layout LyX-Code
+
+jclose(&file);
+\layout Standard
+
+As we've seen, we open the file and initialize the structure with 
+\family typewriter 
+jopen()
+\family default 
+ (with the parameter 
+\emph on 
+jflags
+\emph default 
+ being the last 0)and 
+\family typewriter 
+jtrans_init()
+\family default 
+, then add an operation with 
+\family typewriter 
+jtrans_add()
+\family default 
+ (the last 0 is the offset, in this case the beginning of the file), commit
+ the transaction with 
+\family typewriter 
+jtrans_commit()
+\family default 
+, and finally close the file with 
+\family typewriter 
+jclose()
+\family default 
+.
+\layout Section
+
+Advanced functions
+\layout Subsection
+
+Interaction with reads
+\begin_inset LatexCommand \label{sub:Interaction-with-reads}
+
+\end_inset 
+
+
+\layout Standard
+
+So far we've seen how to use the library to perform writes, but what about
+ reads? The only and main issue with reads is that, because we provide transacti
+on atomicity, a read must never be able to 
+\begin_inset Quotes eld
+\end_inset 
+
+see
+\begin_inset Quotes erd
+\end_inset 
+
+ a transaction partially applied.
+ This is achieved internally by using fine-grained file locks; but you shouldn't
+ mind about it if you use the functions the library gives you because they
+ take care of all the locking.
+\layout Standard
+
+This set of functions are very similar to the UNIX ones (
+\family typewriter 
+read()
+\family default 
+, 
+\family typewriter 
+readv()
+\family default 
+, etc.); and in fact are named after them: they're called 
+\family typewriter 
+jread()
+\family default 
+, 
+\family typewriter 
+jreadv()
+\family default 
+ and 
+\family typewriter 
+jpread()
+\family default 
+; and have the same parameters except for the first one, which instead of
+ a file descriptor is a file structure
+\begin_inset Foot
+collapsed false
+
+\layout Standard
+
+In fact, this set of functions is a part of what is called the 
+\begin_inset Quotes eld
+\end_inset 
+
+UNIX API
+\begin_inset Quotes erd
+\end_inset 
+
+, which is described below.
+\end_inset 
+
+.
+ Bear in mind that transactions are only visible by reads 
+\emph on 
+after
+\emph default 
+ you commit them with 
+\family typewriter 
+jtrans_commit()
+\family default 
+.
+\layout Subsection
+
+Rollback
+\layout Standard
+
+There is a very nice and important feature in transactions, that allow them
+ to be 
+\begin_inset Quotes eld
+\end_inset 
+
+undone
+\begin_inset Quotes erd
+\end_inset 
+
+, which means that you can undo a transaction and leave the file just as
+ it was the moment before applying it.
+ The action of undoing it is called to 
+\emph on 
+rollback
+\emph default 
+, and the function is called 
+\family typewriter 
+jtrans_rollback()
+\family default 
+, which takes the transaction as the only parameter.
+\layout Standard
+
+Be aware that rollbacking a transaction can be dangerous if you're not careful
+ and cause you a lot of troubles.
+ For instance, consider you have two transactions (let's call them 1 and
+ 2, and assume they were applied in that order) that modify the same offset,
+ and you rollback transaction 1; then 2 would be lost.
+ It is not an dangerous operation itself, but its use requires care and
+ thought.
+\layout Subsection
+
+Integrity checking and recovery
+\layout Standard
+
+An essential part of the library is taking care of recovering from crashes
+ and be able to assure a file is consistent.
+ When you're working with the file, this is taking care of; but what when
+ you first open it? To answer that question, the library provides you with
+ a function named 
+\family typewriter 
+jfsck()
+\family default 
+, which checks the integrity of a file and makes sure that everything is
+ consistent.
+ It must be called 
+\begin_inset Quotes eld
+\end_inset 
+
+offline
+\begin_inset Quotes erd
+\end_inset 
+
+, that is when you are not actively committing and rollbacking; it is normally
+ done before calling 
+\family typewriter 
+jopen()
+\family default 
+.
+ Another good practise is call jfsck_cleanup() after calling jfsck() to
+ make sure we're starting up with a fresh clean journal.
+ After both calls, it is safe to assume that the file is and ready to use.
+\layout Standard
+
+You can also do this manually with an utility named 
+\emph on 
+jiofsck
+\emph default 
+, which can be used from the shell to perform the checking and cleanup.
+\layout Section
+
+Disk layout
+\layout Standard
+
+The library creates a single directory for each file opened, named after
+ it.
+ So if we open a file 
+\begin_inset Quotes eld
+\end_inset 
+
+output
+\begin_inset Quotes erd
+\end_inset 
+
+, a directory named 
+\begin_inset Quotes eld
+\end_inset 
+
+.output.jio
+\begin_inset Quotes erd
+\end_inset 
+
+ will be created.
+ We call it the 
+\emph on 
+journal directory
+\emph default 
+, and it's used internally by the library to save temporary data; you shouldn't
+ modify any of the files that are inside it, or move it while it's in use.
+ It doesn't grow much (it only uses space for transactions that are in the
+ process of committing) and gets automatically cleaned while working with
+ it so you can (and should) ignore it.
+ Besides that, the file you work with has no special modification and is
+ just like any other file, all the internal stuff is kept isolated on the
+ journal directory.
+\layout Section
+
+Other APIs
+\layout Standard
+
+We're all used to do things our way, and when we learn something new it's
+ often better if it looks alike what we already know.
+ With this in mind, the library comes with two sets of APIs that look a
+ lot like traditional, well known ones.
+ Bear in mind that they are not as powerful as the transaction API that
+ is described above, and they can't provide the same functionality in a
+ lot of cases; however for a lot of common and simple use patterns they
+ are good enough.
+\layout Subsection
+
+UNIX API
+\layout Standard
+
+There is a set of functions that emulate the UNIX API (
+\family typewriter 
+read()
+\family default 
+, 
+\family typewriter 
+write()
+\family default 
+, and so on) which make each operation a transaction.
+ This can be useful if you don't need to have the full power of the transactions
+ but only to provide guarantees between the different functions.
+ They are a lot like the normal UNIX functions, but instead of getting a
+ file descriptor as their first parameter, they get a file structure.
+ You can check out the manual page to see the details, but they work just
+ like their UNIX version, only that they preserve atomicity and thread-safety
+ 
+\emph on 
+within each call
+\emph default 
+.
+\layout Standard
+
+In particular, the group of functions related to reading (which was described
+ above in 
+\begin_inset LatexCommand \ref{sub:Interaction-with-reads}
+
+\end_inset 
+
+) are extremely useful because they take care of the locking needed for
+ the library proper behaviour.
+ You should use them instead of the regular calls.
+\layout Standard
+
+The full function list is available on the man page and I won't reproduce
+ it here; however the naming is quite simple: just prepend a 'j' to all
+ the names: 
+\family typewriter 
+jread()
+\family default 
+, 
+\family typewriter 
+jwrite()
+\family default 
+, etc.
+\layout Subsection
+
+ANSI C API
+\layout Standard
+
+Besides the UNIX API you can find an ANSI C API, which emulates the traditional
+ 
+\family typewriter 
+fread()
+\family default 
+, 
+\family typewriter 
+fwrite()
+\family default 
+, etc.
+ They're still in development and has not been tested carefully, so I won't
+ spend time documenting them.
+ Let me know if you need them.
+\layout Section
+
+Where to go from here
+\layout Standard
+
+If you're still interested in learning more, you can find some small and
+ clean samples are in the 
+\begin_inset Quotes eld
+\end_inset 
+
+samples
+\begin_inset Quotes erd
+\end_inset 
+
+ directory (full.c is a simple and complete one), other more advanced examples
+ can be found in the web page, as well as modifications to well known software
+ to make use of the library.
+ For more information about the inner workings of the library, you can read
+ the 
+\begin_inset Quotes eld
+\end_inset 
+
+libjio
+\begin_inset Quotes erd
+\end_inset 
+
+ document, and the source code.
+\the_end
diff -puN doc/libjio.lyx~new_commit_doc doc/libjio.lyx
--- cur/doc/libjio.lyx~new_commit_doc	2004-06-19 23:57:46.000000000 -0300
+++ cur-root/doc/libjio.lyx	2004-06-19 23:57:46.000000000 -0300
@@ -56,6 +56,8 @@ This document explains the design of the
  ways, it provides (or at least tries to =) an insight view on how the library
  performs its job, which can be very valuable knowledge when working with
  it.
+ It assumes that there is some basic knowledge about how the library is
+ used, which can be found in the manpage or in the programmer's guide.
 \layout Standard
 
 To the user, libjio provides two groups of functions, one UNIX-alike that
@@ -83,7 +85,7 @@ write()
 The following sections describe different concepts and procedures that the
  library bases its work on.
  It's not intended to be a replace to reading the source code: please do
- so if you have any doubts, it's not big at all (less than 800 lines, including
+ so if you have any doubts, it's not big at all (less than 1500 lines, including
  comments) and I hope it's readable enough.
  If you think that's not the case, please let me know and I'll try to give
  you a hand.
@@ -131,18 +133,12 @@ The transaction file is composed of two 
 \layout Standard
 
 The header holds basic information about the transaction itself, including
- the ID, some flags, the offset to commit to and the lenght of the data.
- The payload holds the data, in three parts: user-defined data, previous
- data, and real data.
-\layout Standard
-
-User-defined data is not used by the library itself, but it's a space where
- the user can save private data that can be useful later.
- Previous data is saved by the library prior applying the commit, so transaction
-s can be rollbacked.
- Real data is just the data to save to the disk, and it is saved because
- if a crash occurs when while we are applying the transaction we can recover
- gracefuly.
+ the ID, some flags, and the amount of operations it includes.
+ Then the payload has all the operations one after the other, divided in
+ two parts: the first one includes static information about the operation
+ (the lenght of the data, the offset of the file where it should be applied,
+ etc.) and the data itself, which is saved by the library prior applying
+ the commit, so transactions can be rollbacked.
 \layout Section
 
 The commit procedure
@@ -165,7 +161,7 @@ safely
 \emph default 
 , means that after a commit has been done we can assume the data will not
  get lost and can be retrieved, unless of course some major event happens
- (like a hardware failure).
+ (like a physical hard disk crash).
  For us, this means that the data was effectively written to the disk and
  if a crash occurs after the commit operation has returned, the operation
  will be complete and data will be available from the file.
@@ -175,7 +171,7 @@ The latter, 
 \emph on 
 atomically
 \emph default 
-, warantees that the operation is either completely done, or not done at
+, guarantees that the operation is either completely done, or not done at
  all.
  This is a really common word, specially if you have worked with multiprocessing
 , and should be quite familiar.
@@ -193,7 +189,7 @@ jtrans_commit()
 :
 \layout Itemize
 
-Lock the section where the commit takes place
+Lock the file offsets where the commit takes place
 \layout Itemize
 
 Open the transaction file
@@ -202,10 +198,7 @@ Open the transaction file
 Write the header
 \layout Itemize
 
-Write the user data (if any)
-\layout Itemize
-
-Read the previous data from the file
+Read all the previous data from the file
 \layout Itemize
 
 Write the previous data in the transaction
@@ -220,7 +213,7 @@ Mark the transaction as commited by sett
 Unlink the transaction file
 \layout Itemize
 
-Unlock the section where the commit takes place
+Unlock the offsets where the commit takes place
 \layout Standard
 
 This may look as a lot of steps, but they're not as much as it looks like
@@ -245,8 +238,8 @@ undo
  and straightforward.
 \layout Standard
 
-In the previous section we said that each transaction held, besides the
- data to commit to the disk, the data that was on it before commiting.
+In the previous section we said that each transaction held the data that
+ was on it before commiting.
  That data is saved precisely to be able to rollback.
  So, to rollback a transaction all that has to be done is recover that 
 \begin_inset Quotes eld
@@ -332,15 +325,15 @@ In any case, after making the recovery y
  transaction atomicity was preserved.
 \layout Section
 
-High-level functions
+UNIX API
 \layout Standard
 
 We call 
 \emph on 
-high-level functions
+UNIX API
 \emph default 
- to the ones provided by the library that emulate the good old unix file
- manipulation calls.
+ to the functions provided by the library that emulate the good old UNIX
+ file manipulation calls.
  Most of them are just wrappers around commits, and implement proper locking
  when operating in order to allow simultaneous operations (either across
  threads or processes).
diff -puN doc/libjio.3~new_commit_doc doc/libjio.3
--- cur/doc/libjio.3~new_commit_doc	2004-06-19 23:57:46.000000000 -0300
+++ cur-root/doc/libjio.3	2004-06-20 00:02:46.000000000 -0300
@@ -24,10 +24,12 @@ libjio - A library for Journaled I/O
 
 .BI "int jclose(struct jfs *" fs " );
 
-.BI "void jtrans_init(struct jfs *" fs " , struct jtrans *" ts " );
+.BI "void jtrans_init(struct jfs *" fs " ,struct jtrans *" ts " );
 
 .BI "int jtrans_commit(struct jtrans *" ts " );
 
+.BI "int jtrans_add(struct jtrans *" ts ", const void * " buf ", size_t " count ", off_t " offset " );
+
 .BI "int jtrans_rollback(struct jtrans *" ts " );
 
 .BI "void jtrans_free(struct jtrans *" ts " );
@@ -40,56 +42,47 @@ libjio - A library for Journaled I/O
 .PP
 .br
 .nf
-.in 10
+.in +2n
 struct jfs {
-.in 14
-int fd;                 /* main file descriptor */
-char *name;             /* and its name */
-int jfd;                /* journal's lock file descriptor */
-int flags;              /* journal mode options used in jopen() */
-pthread_mutex_t lock;   /* a soft lock used in some operations */
-.in 10
+    int fd;                /* main file descriptor */
+    char *name;            /* and its name */
+    int jfd;               /* journal's lock file descriptor */
+    int flags;             /* journal mode options used in jopen() */
+    pthread_mutex_t lock;  /* a soft lock used in some operations */
+    ...
 };
 .FI
+.in -2n
 
 .PP
 .br
 .nf
-.in 10
+.in +2n
 struct jtrans {
-.in 14
-struct jfs *fs;         /* journal file structure to operate on */
-char *name;             /* name of the transaction file */
-int id;                 /* transaction id */
-int flags;              /* misc flags */
-void *buf;              /* buffer */
-size_t len;             /* buffer lenght */
-off_t offset;           /* file offset to operate on */
-void *udata;            /* user-supplied data */
-size_t ulen;            /* udata lenght */
-void *pdata;            /* previous data, for rollback */
-size_t plen;            /* pdata lenght */
-.in 10
+    struct jfs *fs;       /* journal file structure to operate on */
+    char *name;           /* name of the transaction file */
+    int id;               /* transaction id */
+    int flags;            /* misc flags */
+    ...
 };
 .FI
+.in -2n
 
 .PP
 .br
 .nf
-.in 10
+.in +2n
 struct jfsck_result {
-.in 14
-int total;              /* total transactions files we looked at */
-int invalid;            /* invalid files in the journal directory */
-int in_progress;        /* transactions in progress */
-int broken_head;        /* transactions broken (header missing) */
-int broken_body;        /* transactions broken (body missing) */
-int load_error;         /* errors loading the transaction */
-int apply_error;        /* errors applying the transaction */
-int rollbacked;         /* transactions that were rollbacked */
-.in 10
+    int total;            /* total transactions files we looked at */
+    int invalid;          /* invalid files in the journal directory */
+    int in_progress;      /* transactions in progress */
+    int broken;           /* transactions broken */
+    int apply_error;      /* errors applying the transaction */
+    int rollbacked;       /* transactions that were rollbacked */
+    ...
 };
 .FI
+.in -2n
 
 .SH DESCRIPTION
 
@@ -98,15 +91,21 @@ describes it's C API very briefly, furth
 documentation that comes along with the library itself, or on the web at
 http://auriga.wearlab.de/~alb/libjio.
 
-We can group the functions into three groups: a common one, with functions
-common to the other two; low-level one, which consists of jtrans_commit and
-jtrans_rollback. They provide a method for manipulating transactions, which
-are defined in the jtrans structure (described above).
+We can group the functions into three groups: the common functions, the basic
+functions and the UNIX API.
+
+The common functions provide functionality common to the other two: jopen to
+open files to use them with the library, and jfsck and jfsck_cleanup to
+provide integrity checking.
+
+The basic functions consists of jtrans_commit, jtrans_add and jtrans_rollback.
+They provide a method for manipulating transactions, which are defined in the
+jtrans structure (described above).
 
 The second group mimics somehow the traditional UNIX API by providing similar
 interfaces to read(), write(), and their friends.
 
-.SH COMMON API
+.SH Common functions
 
 Most functions reference somehow the structures described avobe, specially
 struct jfs and struct jtrans. They represent a file to operate on and a single
@@ -133,9 +132,9 @@ longer be needed, so by cleaning up the 
 starting over with a clean journal. It returns 0 if there was an error, or 1
 if it succeeded.
 
-.SH HIGH LEVEL API
+.SH UNIX API
 
-The high level API, as explained before, consists of the functions jread(),
+The UNIX API, as explained before, consists of the functions jread(),
 jpread(), jreadv(), jwrite(), jpwrite(), jwritev(), jtruncate(). In most cases
 you will only need to use this, because they're simple and familiar.
 
@@ -146,10 +145,10 @@ like jopen() and jclose()). Again, I wil
 these functions, just refer to the regular UNIX versions to see how to use
 them, they all have the same semantics and behave the same way.
 
-.SH LOW LEVEL API
+.SH Basic functions
 
-The low level functions are the ones which manipulate transactions directly;
-they are four: jtrans_init(), jtrans_commit(), jtrans_rollback() and
+The basic functions are the ones which manipulate transactions directly; they
+are five: jtrans_init(), jtrans_add(), jtrans_commit(), jtrans_rollback() and
 jtrans_free(). These are intended to be use in special situations where your
 application needs direct control over the transactions.
 
@@ -160,10 +159,16 @@ only frees the pointers that were previo
 disk operations are performed by the other two functions. They have no return
 value.
 
-jtrans_commit() is in charge of commiting the given transaction (which data
-was completed by you, and is described in the STRUCTURES section), and after
-its return the data has been saved to the disk atomically. It returns the
-number of bytes written or -1 if there was an error.
+jtrans_add() is used to add operations to a transaction, and it takes the same
+parameters as the pwrite() call. It gets a buffer, it's lenght and the offset
+where it should be applied, and adds it to the transaction. You can add
+multiple operations to a transaction, and they will be applied in order.
+Operation within the same transaction must not overlap; if they do, commiting
+the transaction will fail.
+
+jtrans_commit() is in charge of commiting the given transaction, and after its
+return the data has been saved to the disk atomically. It returns the number
+of bytes written or -1 if there was an error.
 
 jtrans_rollback() reverses a transaction that was applied with
 jtrans_commit(), and leaves the file as it was before applying it. Be very
diff -puN -L doc/big_transactions doc/big_transactions~new_commit_doc /dev/null
--- cur/doc/big_transactions
+++ /dev/null	2004-04-13 23:59:22.000000000 -0300
@@ -1,9 +0,0 @@
-
-If you have to create big transactions, instead of creating a huge buffer you
-can mmap a temporary file and periodically sync it; and when you're done, just
-jtrans_commit() the whole thing.
-
-This would be a quite efficient way, without any performance penalty and a
-very simple approach; I originally thought of doing this on the journal, but
-it had many drawbacks that made it much expensive, slower and complex.
-
diff -puN -L doc/jiofsck doc/jiofsck~new_commit_doc /dev/null
--- cur/doc/jiofsck
+++ /dev/null	2004-04-13 23:59:22.000000000 -0300
@@ -1,12 +0,0 @@
-
-Note that jfsck does not warantee that all the transactions are fully
-completed, it can only do so if you run it without any other process accessing
-the journal.
-
-If you want to see this, you can take a look at the struct jfsck_result. It
-include a field named in_progress which tell the number of transactions that
-were in progress at the moment of checking, and as such weren't checked.
-
-Be aware that the counter is not atomic, as two checkers can be running at the
-same time.
-
diff -puN -L doc/threads doc/threads~new_commit_doc /dev/null
--- cur/doc/threads
+++ /dev/null	2004-04-13 23:59:22.000000000 -0300
@@ -1,20 +0,0 @@
-
-The library is entirely threadsafe.
-
-This will make some people who worked with threads a bit concerned, because
-everybody knows that if a file descriptor is shared among threads, and two
-threads decide to read/write/perform any op that moves the file pointer, a
-mess is waiting to happen. And almost operations do touch the file pointer.
-
-But don't worry, the library is _truly_ threadsafe: it uses pread/pwrite,
-which do not touch the file pointer, and allows working on the same file
-simultaneously without concerns. Besides, it slightly improves performance by
-having less locking, less system calls, lower overhead and less calculation to
-perform the operation.
-
-
-Still, bear in mind that if you decide to work on the file outside libjio you
-need to lockf() the sections you're going to work on, because libjio relies on
-lockf() locking to warantee atomicity.
-
-
diff -puN README~new_commit_doc README
--- cur/README~new_commit_doc	2004-06-20 00:08:58.000000000 -0300
+++ cur-root/README	2004-06-20 00:12:11.000000000 -0300
@@ -16,10 +16,12 @@ special directory is created to store in
 This allows both simple file manipulation, recovery and debugging because
 everything is isolated.
 
-There's a more detailed document about the library itself in doc/libjio.txt
-which is based on doc/libjio.lyx (there are HTML, Postscript, PDF and TXT
-versions in the website, which are not included here for space reasons), and a
-manpage where you will find the API reference.
+There are more detailed documents: a programming guide, a brief introduction
+to the design and inner workings, and the manpage; all in the doc/ directory.
+
+The first two, called 'guide' and 'libjio' respectively, are both in txt and
+lyx formats, with HTML, Postscript and PDF versions in the website, which are
+not included in the package for space reasons.
 
 
 To see how to install it, please read the INSTALL file.
diff -puN doc/libjio.txt~new_commit_doc doc/libjio.txt
--- cur/doc/libjio.txt~new_commit_doc	2004-06-20 00:17:28.402257568 -0300
+++ cur-root/doc/libjio.txt	2004-06-20 00:18:06.834414992 -0300
@@ -10,7 +10,7 @@ Table of Contents
 3 The commit procedure
 4 The rollback procedure
 5 The recovery procedure
-6 High-level functions
+6 UNIX API
 7 ACID (or How does libjio fit into theory)
 8 Working from outside
 
@@ -28,7 +28,9 @@ should read it even if you don't plan to
 library in strange ways, it provides (or at least tries 
 to =) an insight view on how the library performs its 
 job, which can be very valuable knowledge when working 
-with it.
+with it. It assumes that there is some basic knowledge 
+about how the library is used, which can be found in 
+the manpage or in the programmer's guide.
 
 To the user, libjio provides two groups of functions, 
 one UNIX-alike that implements the journaled versions 
@@ -46,7 +48,7 @@ The following sections describe differen
 procedures that the library bases its work on. It's not 
 intended to be a replace to reading the source code: 
 please do so if you have any doubts, it's not big at 
-all (less than 800 lines, including comments) and I 
+all (less than 1500 lines, including comments) and I 
 hope it's readable enough. If you think that's not the 
 case, please let me know and I'll try to give you a hand.
 
@@ -88,19 +90,14 @@ The transaction file is composed of two 
 header and the payload.
 
 The header holds basic information about the 
-transaction itself, including the ID, some flags, the 
-offset to commit to and the lenght of the data. The 
-payload holds the data, in three parts: user-defined 
-data, previous data, and real data.
-
-User-defined data is not used by the library itself, 
-but it's a space where the user can save private data 
-that can be useful later. Previous data is saved by the 
-library prior applying the commit, so transactions can 
-be rollbacked. Real data is just the data to save to 
-the disk, and it is saved because if a crash occurs 
-when while we are applying the transaction we can 
-recover gracefuly.
+transaction itself, including the ID, some flags, and 
+the amount of operations it includes. Then the payload 
+has all the operations one after the other, divided in 
+two parts: the first one includes static information 
+about the operation (the lenght of the data, the offset 
+of the file where it should be applied, etc.) and the 
+data itself, which is saved by the library prior 
+applying the commit, so transactions can be rollbacked.
 
 3 The commit procedure
 
@@ -110,15 +107,15 @@ write some given data to the disk.
 The former, safely, means that after a commit has been 
 done we can assume the data will not get lost and can 
 be retrieved, unless of course some major event happens 
-(like a hardware failure). For us, this means that the 
-data was effectively written to the disk and if a crash 
-occurs after the commit operation has returned, the 
-operation will be complete and data will be available 
-from the file.
-
-The latter, atomically, warantees that the operation is 
-either completely done, or not done at all. This is a 
-really common word, specially if you have worked with 
+(like a physical hard disk crash). For us, this means 
+that the data was effectively written to the disk and 
+if a crash occurs after the commit operation has 
+returned, the operation will be complete and data will 
+be available from the file.
+
+The latter, atomically, guarantees that the operation 
+is either completely done, or not done at all. This is 
+a really common word, specially if you have worked with 
 multiprocessing, and should be quite familiar. We 
 implement atomicity by combining fine-grained locks and 
 journaling, which can assure us both to be able to 
@@ -130,15 +127,13 @@ Well, so much for talking, now let's get
 applies commits in a very simple and straightforward 
 way, inside jtrans_commit():
 
-* Lock the section where the commit takes place
+* Lock the file offsets where the commit takes place
 
 * Open the transaction file
 
 * Write the header
 
-* Write the user data (if any)
-
-* Read the previous data from the file
+* Read all the previous data from the file
 
 * Write the previous data in the transaction
 
@@ -149,7 +144,7 @@ way, inside jtrans_commit():
 
 * Unlink the transaction file
 
-* Unlock the section where the commit takes place
+* Unlock the offsets where the commit takes place
 
 This may look as a lot of steps, but they're not as 
 much as it looks like inside the code, and allows a 
@@ -164,17 +159,16 @@ commit was applied. Due to the way we ha
 doing this operation becomes quite simple and straightforward.
 
 In the previous section we said that each transaction 
-held, besides the data to commit to the disk, the data 
-that was on it before commiting. That data is saved 
-precisely to be able to rollback. So, to rollback a 
-transaction all that has to be done is recover that "
-previous data" from the transaction we want to rollback, 
-and save it to the disk. In the end, this ends up being 
-a new transaction with the previous data as the new 
-one, so we do that: create a new transaction structure, 
-fill in the data from the transaction we want to 
-rollback, and commit it. All this is performed by 
-jtrans_rollback().
+held the data that was on it before commiting. That 
+data is saved precisely to be able to rollback. So, to 
+rollback a transaction all that has to be done is 
+recover that "previous data" from the transaction we want 
+to rollback, and save it to the disk. In the end, this 
+ends up being a new transaction with the previous data 
+as the new one, so we do that: create a new transaction 
+structure, fill in the data from the transaction we 
+want to rollback, and commit it. All this is performed 
+by jtrans_rollback().
 
 By doing this we can provide the same warranties a 
 commit has, it's really fast, eases the recovery, and 
@@ -220,10 +214,10 @@ remove the journal entirely and let the 
 a new one, and you can be sure that transaction 
 atomicity was preserved.
 
-6 High-level functions
+6 UNIX API
 
-We call high-level functions to the ones provided by 
-the library that emulate the good old unix file 
+We call UNIX API to the functions provided by the 
+library that emulate the good old UNIX file 
 manipulation calls. Most of them are just wrappers 
 around commits, and implement proper locking when 
 operating in order to allow simultaneous operations 
diff -puN /dev/null doc/guide.txt
--- /dev/null	2004-04-13 23:59:22.000000000 -0300
+++ cur-root/doc/guide.txt	2004-06-20 00:21:59.026116488 -0300
@@ -0,0 +1,295 @@
+libjio Programmer's Guide
+
+Alberto Bertogli (albertogli@telpin.com.ar)
+
+Table of Contents
+
+1 Introduction
+2 Definitions
+3 The data types
+4 The basic functions
+5 Advanced functions
+    5.1 Interaction with reads
+    5.2 Rollback
+    5.3 Integrity checking and recovery
+6 Disk layout
+7 Other APIs
+    7.1 UNIX API
+    7.2 ANSI C API
+8 Where to go from here
+
+
+
+1 Introduction
+
+This small document attempts serve as a guide to the 
+programmer who wants to make use of the library. It's 
+not a replacement for the man page or reading the code; 
+but it's a good starting point for everyone who wants 
+to get involved with it.
+
+The library is not complex to use at all, and the 
+interfaces were designed to be as intuitive as 
+possible, so the text is structured as a guide to 
+present the reader all the common structures and 
+functions the way they're normally used.
+
+2 Definitions
+
+This is a library which provides a journaled 
+transaction-oriented I/O API. You've probably read this 
+a hundred times already in the documents, and if you 
+haven't wondered yet what on earth does this mean you 
+should be reading something else!
+
+We say this is a transaction-oriented API because we 
+make transactions the center of our operations, and 
+journaled because we use a journal (which takes the 
+form of a directory with files on it) to guarantee 
+coherency even after a crash at any point.
+
+Here we think a transaction as a list of (buffer, 
+length, offset) to be applied to a file. That triple is 
+called an operation, so we can say that a transaction 
+represent an ordered group of operations on the same file.
+
+The act of committing a transaction means writing all 
+the elements of the list; and rollbacking means to undo 
+a previous commit, and leave the data just as it was 
+before doing the commit (while all this definitions may
+seem obvious to some people, it requires special attention
+because there are a lot of different definitions, and it's
+not that common to see "transaction" applied to file I/O
+(it's a term used mostly on database stuff), so it's
+important to clarify before continuing).
+
+It's important to note that the library not only 
+provides a convenient and easy API to perform this kind 
+of operations, but provides a lot of guarantees while 
+doing this. The most relevant and useful is that at any 
+point of time, even if we crash horribly, a transaction 
+will be either fully applied or not applied at all. You 
+should not ever see partial transactions or any kind of 
+data corruption.
+
+To achieve this, the library uses what is called a 
+journal, a very vague (and fashionable) term we use to 
+describe a set of auxiliary files that get created to 
+store temporary data at several stages. The proper 
+definition and how we use them is outside the scope of 
+this document, and you as a programmer shouldn't need 
+to deal with it. In case you're curious, it's described 
+in a bit more detail in another text which talks about 
+how the library works internally. Now let's get real.
+
+3 The data types
+
+To understand any library, it's essential to be 
+confident in the knowledge of their data structures and 
+how they relate each other. In libjio we have two basic 
+structures which have a very strong relationship, and 
+represent the essential objects we deal with. Note that 
+you normally don't manipulate them directly, because 
+they have their own initializer functions, but they are 
+the building blocks for the rest of the text, which, 
+once this is understood, is obvious and self-evident.
+
+The first structure we face is struct jfs, called the 
+file structure, and it represents an open file, just 
+like a regular file descriptor or a FILE *.
+
+Then you find struct jtrans, called the transaction 
+structure, which represents a single transaction. You 
+can have as many transactions as you want, and operate 
+on all of them simultaneously without problems; the 
+library is entirely thread safe so there's no need to 
+worry about that.
+
+4 The basic functions
+
+Now that we've described our data types, let's see how 
+we can really operate with the library. 
+
+First of all, as with regular I/O, you need to open 
+your files. This is done with jopen(), which looks a 
+lot like open() but takes a file structure instead of a 
+file descriptor (this will be very common among all the 
+functions), and adds a new parameter jflags that can be 
+used to modify some subtle library behaviour we'll see 
+later, and it's normally not used.
+
+We have a happy file structure open now, and the next 
+thing to do would be to create a transaction. This is 
+what jtrans_init() is for: it takes a file structure 
+and a transaction structure and initializes the latter, 
+leaving it ready to use.
+
+So we have our transaction, let's add a write operation 
+to it; to do this we use jtrans_add(). We could keep on 
+adding operations to the transaction by keep on calling 
+jtrans_add() as many times as we want.
+
+Finally, we decide to apply our transaction to the 
+file, that is, write all the operations we've added. 
+And this is the easiest part: we call jtrans_commit(), 
+and that's it!
+
+When we're done using the file, we call jclose(), just 
+like we call close().
+
+Let's put it all together and code a nice "hello world" 
+program (return values are ignored for simplicity):
+
+char buf[] = "Hello world!";
+struct jfs file;
+struct jtrans trans;
+
+jopen(&file, "filename", O_RDWR | O_CREAT, 0600, 0);
+jtrans_init(&file, &trans);
+jtrans_add(&trans, buf, strlen(buf), 0);
+
+jtrans_commit(&trans);
+
+jclose(&file);
+
+As we've seen, we open the file and initialize the 
+structure with jopen() (with the parameter jflags being 
+the last 0)and jtrans_init(), then add an operation 
+with jtrans_add() (the last 0 is the offset, in this 
+case the beginning of the file), commit the transaction 
+with jtrans_commit(), and finally close the file with jclose().
+
+5 Advanced functions
+
+5.1 Interaction with reads
+
+So far we've seen how to use the library to perform 
+writes, but what about reads? The only and main issue 
+with reads is that, because we provide transaction 
+atomicity, a read must never be able to "see" a 
+transaction partially applied. This is achieved 
+internally by using fine-grained file locks; but you 
+shouldn't mind about it if you use the functions the 
+library gives you because they take care of all the locking.
+
+This set of functions are very similar to the UNIX ones 
+(read(), readv(), etc.); and in fact are named after 
+them: they're called jread(), jreadv() and jpread(); 
+and have the same parameters except for the first one, 
+which instead of a file descriptor is a file structure (in
+fact, this set of functions is a part of what is called
+the "UNIX API", which is described below). Bear in mind
+that transactions are only visible by reads after you
+commit them with jtrans_commit().
+
+5.2 Rollback
+
+There is a very nice and important feature in 
+transactions, that allow them to be "undone", which means 
+that you can undo a transaction and leave the file just 
+as it was the moment before applying it. The action of 
+undoing it is called to rollback, and the function is 
+called jtrans_rollback(), which takes the transaction 
+as the only parameter.
+
+Be aware that rollbacking a transaction can be 
+dangerous if you're not careful and cause you a lot of 
+troubles. For instance, consider you have two 
+transactions (let's call them 1 and 2, and assume they 
+were applied in that order) that modify the same 
+offset, and you rollback transaction 1; then 2 would be 
+lost. It is not an dangerous operation itself, but its 
+use requires care and thought.
+
+5.3 Integrity checking and recovery
+
+An essential part of the library is taking care of 
+recovering from crashes and be able to assure a file is 
+consistent. When you're working with the file, this is 
+taking care of; but what when you first open it? To 
+answer that question, the library provides you with a 
+function named jfsck(), which checks the integrity of a 
+file and makes sure that everything is consistent. It 
+must be called "offline", that is when you are not 
+actively committing and rollbacking; it is normally 
+done before calling jopen(). Another good practise is 
+call jfsck_cleanup() after calling jfsck() to make sure 
+we're starting up with a fresh clean journal. After 
+both calls, it is safe to assume that the file is and 
+ready to use.
+
+You can also do this manually with an utility named 
+jiofsck, which can be used from the shell to perform 
+the checking and cleanup.
+
+6 Disk layout
+
+The library creates a single directory for each file 
+opened, named after it. So if we open a file "output", a 
+directory named ".output.jio" will be created. We call it 
+the journal directory, and it's used internally by the 
+library to save temporary data; you shouldn't modify 
+any of the files that are inside it, or move it while 
+it's in use. It doesn't grow much (it only uses space 
+for transactions that are in the process of committing) 
+and gets automatically cleaned while working with it so 
+you can (and should) ignore it. Besides that, the file 
+you work with has no special modification and is just 
+like any other file, all the internal stuff is kept 
+isolated on the journal directory.
+
+7 Other APIs
+
+We're all used to do things our way, and when we learn 
+something new it's often better if it looks alike what 
+we already know. With this in mind, the library comes 
+with two sets of APIs that look a lot like traditional, 
+well known ones. Bear in mind that they are not as 
+powerful as the transaction API that is described 
+above, and they can't provide the same functionality in 
+a lot of cases; however for a lot of common and simple 
+use patterns they are good enough.
+
+7.1 UNIX API
+
+There is a set of functions that emulate the UNIX API 
+(read(), write(), and so on) which make each operation 
+a transaction. This can be useful if you don't need to 
+have the full power of the transactions but only to 
+provide guarantees between the different functions. 
+They are a lot like the normal UNIX functions, but 
+instead of getting a file descriptor as their first 
+parameter, they get a file structure. You can check out 
+the manual page to see the details, but they work just 
+like their UNIX version, only that they preserve 
+atomicity and thread-safety within each call.
+
+In particular, the group of functions related to reading
+(which was described above in "Interaction with reads")
+are extremely useful because they take care of the locking
+needed for the library proper behaviour. You should use
+them instead of the regular calls.
+
+The full function list is available on the man page and 
+I won't reproduce it here; however the naming is quite 
+simple: just prepend a 'j' to all the names: jread(), 
+jwrite(), etc.
+
+7.2 ANSI C API
+
+Besides the UNIX API you can find an ANSI C API, which 
+emulates the traditional fread(), fwrite(), etc. 
+They're still in development and has not been tested 
+carefully, so I won't spend time documenting them. Let 
+me know if you need them.
+
+8 Where to go from here
+
+If you're still interested in learning more, you can 
+find some small and clean samples are in the "samples" 
+directory (full.c is a simple and complete one), other 
+more advanced examples can be found in the web page, as 
+well as modifications to well known software to make 
+use of the library. For more information about the 
+inner workings of the library, you can read the "libjio" 
+document, and the source code.

_
