<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>

<book id="LinuxJBDAPI">
 <bookinfo>
  <title>The Linux Journalling API</title>
  <authorgroup>
  <author>
     <firstname>Roger</firstname>
     <surname>Gammans</surname>
     <affiliation>
     <address>
      <email>rgammans@computer-surgery.co.uk</email>
     </address>
    </affiliation>
     </author> 
  </authorgroup>
  
  <authorgroup>
   <author>
    <firstname>Stephen</firstname>
    <surname>Tweedie</surname>
    <affiliation>
     <address>
      <email>sct@redhat.com</email>
     </address>
    </affiliation>
   </author>
  </authorgroup>

  <copyright>
   <year>2002</year>
   <holder>Roger Gammans</holder>
  </copyright>

<legalnotice>
   <para>
     This documentation is free software; you can redistribute
     it and/or modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
     version 2 of the License, or (at your option) any later
     version.
   </para>
      
   <para>
     This program is distributed in the hope that it will be
     useful, but WITHOUT ANY WARRANTY; without even the implied
     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     See the GNU General Public License for more details.
   </para>
      
   <para>
     You should have received a copy of the GNU General Public
     License along with this program; if not, write to the Free
     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     MA 02111-1307 USA
   </para>
      
   <para>
     For more details see the file COPYING in the source
     distribution of Linux.
   </para>
  </legalnotice>
 </bookinfo>

<toc></toc>

  <chapter id="Overview">
     <title>Overview</title>
  <sect1>
     <title>Details</title>
<para>
The journalling layer is  easy to use. You need to 
first of all create a journal_t data structure. There are
two calls to do this dependent on how you decide to allocate the physical
media on which the journal resides. The journal_init_inode() call 
is for journals stored in filesystem inodes, or the journal_init_dev()
call can be use for journal stored on a raw device (in a continuous range 
of blocks). A journal_t is a typedef for a struct pointer, so when
you are finally finished make sure you call journal_destroy() on it
to free up any used kernel memory.
</para>

<para>
Once you have got your journal_t object you need to 'mount' or load the journal
file, unless of course you haven't initialised it yet - in which case you
need to call journal_create().
</para>

<para>
Most of the time however your journal file will already have been created, but
before you load it you must call journal_wipe() to empty the journal file.
Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the 
job of the client file system to detect this and skip the call to journal_wipe().
</para>

<para>
In either case the next call should be to journal_load() which prepares the
journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() 
for you if it detects any outstanding transactions in the journal and similarly
journal_load() will call journal_recover() if necessary.
I would advise reading fs/ext3/super.c for examples on this stage.
[RGG: Why is the journal_wipe() call necessary - doesn't this needlessly 
complicate the API. Or isn't a good idea for the journal layer to hide 
dirty mounts from the client fs]
</para>

<para>
Now you can go ahead and start modifying the underlying 
filesystem. Almost.
</para>


<para>

You still need to actually journal your filesystem changes, this
is done by wrapping them into transactions. Additionally you
also need to wrap the modification of each of the buffers
with calls to the journal layer, so it knows what the modifications
you are actually making are. To do this use  journal_start() which
returns a transaction handle.
</para>

<para>
journal_start()
and its counterpart journal_stop(), which indicates the end of a transaction
are nestable calls, so you can reenter a transaction if necessary,
but remember you must call journal_stop() the same number of times as
journal_start() before the transaction is completed (or more accurately
leaves the update phase). Ext3/VFS makes use of this feature to simplify
quota support.
</para>

<para>
Inside each transaction you need to wrap the modifications to the
individual buffers (blocks). Before you start to modify a buffer you
need to call journal_get_{create,write,undo}_access() as appropriate,
this allows the journalling layer to copy the unmodified data if it
needs to. After all the buffer may be part of a previously uncommitted
transaction. 
At this point you are at last ready to modify a buffer, and once
you are have done so you need to call journal_dirty_{meta,}data().
Or if you've asked for access to a buffer you now know is now longer 
required to be pushed back on the device you can call journal_forget()
in much the same way as you might have used bforget() in the past.
</para>

<para>
A journal_flush() may be called at any time to commit and checkpoint
all your transactions.
</para>

<para>
Then at umount time , in your put_super() (2.4) or write_super() (2.5)
you can then call journal_destroy() to clean up your in-core journal object.
</para>


<para>
Unfortunately there a couple of ways the journal layer can cause a deadlock.
The first thing to note is that each task can only have
a single outstanding transaction at any one time, remember nothing
commits until the outermost journal_stop(). This means
you must complete the transaction at the end of each file/inode/address
etc. operation you perform, so that the journalling system isn't re-entered
on another journal. Since transactions can't be nested/batched 
across differing journals, and another filesystem other than
yours (say ext3) may be modified in a later syscall.
</para>

<para>
The second case to bear in mind is that journal_start() can 
block if there isn't enough space in the journal for your transaction 
(based on the passed nblocks param) - when it blocks it merely(!) needs to
wait for transactions to complete and be committed from other tasks, 
so essentially we are waiting for journal_stop(). So to avoid 
deadlocks you must treat journal_start/stop() as if they
were semaphores and include them in your semaphore ordering rules to prevent 
deadlocks. Note that journal_extend() has similar blocking behaviour to
journal_start() so you can deadlock here just as easily as on journal_start().
</para>

<para>
Try to reserve the right number of blocks the first time. ;-). This will
be the maximum number of blocks you are going to touch in this transaction.
I advise having a look at at least ext3_jbd.h to see the basis on which 
ext3 uses to make these decisions.
</para>

<para>
Another wriggle to watch out for is your on-disk block allocation strategy.
why? Because, if you undo a delete, you need to ensure you haven't reused any
of the freed blocks in a later transaction. One simple way of doing this
is make sure any blocks you allocate only have checkpointed transactions
listed against them. Ext3 does this in ext3_test_allocatable(). 
</para>

<para>
Lock is also providing through journal_{un,}lock_updates(),
ext3 uses this when it wants a window with a clean and stable fs for a moment.
eg. 
</para>

<programlisting>

	journal_lock_updates() //stop new stuff happening..
	journal_flush()        // checkpoint everything.
	..do stuff on stable fs
	journal_unlock_updates() // carry on with filesystem use.
</programlisting>

<para>
The opportunities for abuse and DOS attacks with this should be obvious,
if you allow unprivileged userspace to trigger codepaths containing these
calls.
</para>

<para>
A new feature of jbd since 2.5.25 is commit callbacks with the new
journal_callback_set() function you can now ask the journalling layer
to call you back when the transaction is finally committed to disk, so that
you can do some of your own management. The key to this is the journal_callback
struct, this maintains the internal callback information but you can
extend it like this:-
</para>
<programlisting>
	struct  myfs_callback_s {
		//Data structure element required by jbd..
		struct journal_callback for_jbd;
		// Stuff for myfs allocated together.
		myfs_inode*    i_commited;
	
	}
</programlisting>

<para>
this would be useful if you needed to know when data was committed to a 
particular inode.
</para>

</sect1>

<sect1>
<title>Summary</title>
<para>
Using the journal is a matter of wrapping the different context changes,
being each mount, each modification (transaction) and each changed buffer
to tell the journalling layer about them.
</para>

<para>
Here is a some pseudo code to give you an idea of how it works, as
an example.
</para>

<programlisting>
  journal_t* my_jnrl = journal_create();
  journal_init_{dev,inode}(jnrl,...)
  if (clean) journal_wipe();
  journal_load();

   foreach(transaction) { /*transactions must be 
                            completed before
                            a syscall returns to 
                            userspace*/

          handle_t * xct=journal_start(my_jnrl);
          foreach(bh) {
                journal_get_{create,write,undo}_access(xact,bh);
                if ( myfs_modify(bh) ) { /* returns true 
                                        if makes changes */
                           journal_dirty_{meta,}data(xact,bh);
                } else {
                           journal_forget(bh);
                }
          }
          journal_stop(xct);
   }
   journal_destroy(my_jrnl);
</programlisting>
</sect1>

</chapter>

  <chapter id="adt">
     <title>Data Types</title>
     <para>	
	The journalling layer uses typedefs to 'hide' the concrete definitions
	of the structures used. As a client of the JBD layer you can
	just rely on the using the pointer as a magic cookie  of some sort.
	
	Obviously the hiding is not enforced as this is 'C'.
	</para>
	<sect1><title>Structures</title>
<!-- include/linux/jbd.h -->
<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-typedef-handle-t">typedef handle_t</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>typedef handle_t</refname>
 <refpurpose>
   The handle_t type represents a single atomic update being performed by some process.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <synopsis>typedef handle_t;</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
   </para><para>

   All filesystem modifications made by the process go
   through this handle.  Recursive operations (such as quota operations)
   are gathered into a single update.
   </para><para>

   The buffer credits field is used to account for journaled buffers
   being modified by the running process.  To ensure that there is
   enough log space for all outstanding operations, we need to limit the
   number of outstanding buffers possible at any time.  When the
   operation completes, any buffer credits not used are credited back to
   the transaction, so that at all times we know how many buffers the
   outstanding updates on a transaction might possibly touch. 
   </para><para>

   This is an opaque datatype.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-typedef-journal-t">typedef journal_t</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>typedef journal_t</refname>
 <refpurpose>
      The journal_t maintains all of the journaling state information for a single filesystem.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <synopsis>typedef journal_t;</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
   </para><para>

   journal_t is linked to from the fs superblock structure.
   </para><para>

   We use the journal_t to keep track of all outstanding transaction
   activity on the filesystem, and to manage the state of the log
   writing process.
   </para><para>

   This is an opaque datatype.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-struct-handle-s">struct handle_s</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>struct handle_s</refname>
 <refpurpose>
      The handle_s type is the concrete type associated with
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <programlisting>
struct handle_s {
  transaction_t * h_transaction;
  int h_buffer_credits;
  int h_ref;
  int h_err;
  unsigned int h_sync:1;
  unsigned int h_jdata:1;
  unsigned int h_aborted:1;
};  </programlisting>
</refsynopsisdiv>
 <refsect1>
  <title>Members</title>
  <variablelist>
    <varlistentry>      <term>h_transaction</term>
      <listitem><para>
   Which compound transaction is this update a part of?
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>h_buffer_credits</term>
      <listitem><para>
   Number of remaining buffers we are allowed to dirty.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>h_ref</term>
      <listitem><para>
   Reference count on this handle
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>h_err</term>
      <listitem><para>
   Field for caller's use to track errors through large fs operations
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>h_sync</term>
      <listitem><para>
   flag for sync-on-close
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>h_jdata</term>
      <listitem><para>
   flag to force data journaling
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>h_aborted</term>
      <listitem><para>
   flag indicating fatal error on handle
      </para></listitem>
    </varlistentry>
  </variablelist>
 </refsect1>
<refsect1>
<title>Description</title>
<para>
   handle_t.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-struct-journal-s">struct journal_s</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>struct journal_s</refname>
 <refpurpose>
      The journal_s type is the concrete type associated with
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <programlisting>
struct journal_s {
  unsigned long j_flags;
  int j_errno;
  struct buffer_head * j_sb_buffer;
  journal_superblock_t * j_superblock;
  int j_format_version;
  spinlock_t j_state_lock;
  int j_barrier_count;
  struct mutex j_barrier;
  transaction_t * j_running_transaction;
  transaction_t * j_committing_transaction;
  transaction_t * j_checkpoint_transactions;
  wait_queue_head_t j_wait_transaction_locked;
  wait_queue_head_t j_wait_logspace;
  wait_queue_head_t j_wait_done_commit;
  wait_queue_head_t j_wait_checkpoint;
  wait_queue_head_t j_wait_commit;
  wait_queue_head_t j_wait_updates;
  struct mutex j_checkpoint_mutex;
  unsigned long j_head;
  unsigned long j_tail;
  unsigned long j_free;
  unsigned long j_first;
  unsigned long j_last;
  struct block_device * j_dev;
  int j_blocksize;
  unsigned int j_blk_offset;
  struct block_device * j_fs_dev;
  unsigned int j_maxlen;
  spinlock_t j_list_lock;
  struct inode * j_inode;
  tid_t j_tail_sequence;
  tid_t j_transaction_sequence;
  tid_t j_commit_sequence;
  tid_t j_commit_request;
  __u8 j_uuid[16];
  struct task_struct * j_task;
  int j_max_transaction_buffers;
  unsigned long j_commit_interval;
  struct timer_list j_commit_timer;
  spinlock_t j_revoke_lock;
  struct jbd_revoke_table_s * j_revoke;
  struct jbd_revoke_table_s * j_revoke_table[2];
  struct buffer_head ** j_wbuf;
  int j_wbufsize;
  pid_t j_last_sync_writer;
  void * j_private;
};  </programlisting>
</refsynopsisdiv>
 <refsect1>
  <title>Members</title>
  <variablelist>
    <varlistentry>      <term>j_flags</term>
      <listitem><para>
    General journaling state flags
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_errno</term>
      <listitem><para>
    Is there an outstanding uncleared error on the journal (from a
   prior abort)? 
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_sb_buffer</term>
      <listitem><para>
   First part of superblock buffer
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_superblock</term>
      <listitem><para>
   Second part of superblock buffer
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_format_version</term>
      <listitem><para>
   Version of the superblock format
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_state_lock</term>
      <listitem><para>
   Protect the various scalars in the journal
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_barrier_count</term>
      <listitem><para>
    Number of processes waiting to create a barrier lock
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_barrier</term>
      <listitem><para>
   The barrier lock itself
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_running_transaction</term>
      <listitem><para>
   The current running transaction..
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_committing_transaction</term>
      <listitem><para>
   the transaction we are pushing to disk
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_checkpoint_transactions</term>
      <listitem><para>
   a linked circular list of all transactions
   waiting for checkpointing
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wait_transaction_locked</term>
      <listitem><para>
   Wait queue for waiting for a locked transaction
   to start committing, or for a barrier lock to be released
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wait_logspace</term>
      <listitem><para>
   Wait queue for waiting for checkpointing to complete
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wait_done_commit</term>
      <listitem><para>
   Wait queue for waiting for commit to complete 
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wait_checkpoint</term>
      <listitem><para>
    Wait queue to trigger checkpointing
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wait_commit</term>
      <listitem><para>
   Wait queue to trigger commit
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wait_updates</term>
      <listitem><para>
   Wait queue to wait for updates to complete
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_checkpoint_mutex</term>
      <listitem><para>
   Mutex for locking against concurrent checkpoints
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_head</term>
      <listitem><para>
   Journal head - identifies the first unused block in the journal
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_tail</term>
      <listitem><para>
   Journal tail - identifies the oldest still-used block in the
   journal.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_free</term>
      <listitem><para>
   Journal free - how many free blocks are there in the journal?
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_first</term>
      <listitem><para>
   The block number of the first usable block 
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_last</term>
      <listitem><para>
   The block number one beyond the last usable block
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_dev</term>
      <listitem><para>
   Device where we store the journal
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_blocksize</term>
      <listitem><para>
   blocksize for the location where we store the journal.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_blk_offset</term>
      <listitem><para>
   starting block offset for into the device where we store the
   journal
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_fs_dev</term>
      <listitem><para>
   Device which holds the client fs.  For internal journal this will
   be equal to j_dev
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_maxlen</term>
      <listitem><para>
   Total maximum capacity of the journal region on disk.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_list_lock</term>
      <listitem><para>
   Protects the buffer lists and internal buffer state.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_inode</term>
      <listitem><para>
   Optional inode where we store the journal.  If present, all journal
   block numbers are mapped into this inode via <function>bmap</function>.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_tail_sequence</term>
      <listitem><para>
    Sequence number of the oldest transaction in the log 
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_transaction_sequence</term>
      <listitem><para>
   Sequence number of the next transaction to grant
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_commit_sequence</term>
      <listitem><para>
   Sequence number of the most recently committed
   transaction
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_commit_request</term>
      <listitem><para>
   Sequence number of the most recent transaction wanting
   commit 
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_uuid[16]</term>
      <listitem><para>
   Uuid of client object.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_task</term>
      <listitem><para>
   Pointer to the current commit thread for this journal
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_max_transaction_buffers</term>
      <listitem><para>
    Maximum number of metadata buffers to allow in a
   single compound commit transaction
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_commit_interval</term>
      <listitem><para>
   What is the maximum transaction lifetime before we begin
   a commit?
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_commit_timer</term>
      <listitem><para>
    The timer used to wakeup the commit thread
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_revoke_lock</term>
      <listitem><para>
   Protect the revoke table
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_revoke</term>
      <listitem><para>
   The revoke table - maintains the list of revoked blocks in the
   current transaction.
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_revoke_table[2]</term>
      <listitem><para>
   alternate revoke tables for j_revoke
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wbuf</term>
      <listitem><para>
   array of buffer_heads for journal_commit_transaction
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_wbufsize</term>
      <listitem><para>
   maximum number of buffer_heads allowed in j_wbuf, the
   number that will fit in j_blocksize
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_last_sync_writer</term>
      <listitem><para>
   most recent pid which did a synchronous write
      </para></listitem>
    </varlistentry>
    <varlistentry>      <term>j_private</term>
      <listitem><para>
   An opaque pointer to fs-private information.
      </para></listitem>
    </varlistentry>
  </variablelist>
 </refsect1>
<refsect1>
<title>Description</title>
<para>
   journal_t.
</para>
</refsect1>
</refentry>

	</sect1>
</chapter>

  <chapter id="calls">
     <title>Functions</title>
     <para>	
	The functions here are split into two groups those that
	affect a journal as a whole, and those which are used to
	manage transactions
</para>
	<sect1><title>Journal Level</title>
<!-- fs/jbd/journal.c -->
<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-init-dev">journal_init_dev</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_init_dev</refname>
 <refpurpose>
   creates an initialises a journal structure
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>journal_t * <function>journal_init_dev </function></funcdef>
   <paramdef>struct block_device * <parameter>bdev</parameter></paramdef>
   <paramdef>struct block_device * <parameter>fs_dev</parameter></paramdef>
   <paramdef>int <parameter>start</parameter></paramdef>
   <paramdef>int <parameter>len</parameter></paramdef>
   <paramdef>int <parameter>blocksize</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>bdev</parameter></term>
   <listitem>
    <para>
     Block device on which to create the journal
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>fs_dev</parameter></term>
   <listitem>
    <para>
     Device which hold journalled filesystem for this journal.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>start</parameter></term>
   <listitem>
    <para>
     Block nr Start of journal.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>len</parameter></term>
   <listitem>
    <para>
      Lenght of the journal in blocks.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>blocksize</parameter></term>
   <listitem>
    <para>
     blocksize of journalling device
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   journal_init_dev creates a journal which maps a fixed contiguous
   range of blocks on an arbitrary block device.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-init-inode">journal_init_inode</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_init_inode</refname>
 <refpurpose>
      creates a journal which maps to a inode.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>journal_t * <function>journal_init_inode </function></funcdef>
   <paramdef>struct inode * <parameter>inode</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>inode</parameter></term>
   <listitem>
    <para>
     An inode to create the journal in
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   journal_init_inode creates a journal which maps an on-disk inode as
   the journal.  The inode must exist already, must support <function>bmap</function> and
   must have all data blocks preallocated.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-create">journal_create</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_create</refname>
 <refpurpose>
      Initialise the new journal file
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_create </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to create. This structure must have been initialised
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Given a journal_t structure which tells us which disk blocks we can
   use, create a new journal superblock and initialise all of the
   journal fields from scratch.  
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-update-superblock">journal_update_superblock</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_update_superblock</refname>
 <refpurpose>
      Update journal sb on disk.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>journal_update_superblock </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>int <parameter>wait</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     The journal to update.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>wait</parameter></term>
   <listitem>
    <para>
     Set to '0' if you don't want to wait for IO completion.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Update a journal's dynamic superblock fields and write it to disk,
   optionally waiting for the IO to complete.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-load">journal_load</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_load</refname>
 <refpurpose>
      Read journal from disk.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_load </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to act on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Given a journal_t structure which tells us which disk blocks contain
   a journal, read the journal from disk to initialise the in-memory
   structures.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-destroy">journal_destroy</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_destroy</refname>
 <refpurpose>
      Release a journal_t structure.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>journal_destroy </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to act on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Release a journal_t structure once it is no longer in use by the
   journaled object.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-check-used-features">journal_check_used_features</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_check_used_features</refname>
 <refpurpose>
      Check if features specified are used.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_check_used_features </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>unsigned long <parameter>compat</parameter></paramdef>
   <paramdef>unsigned long <parameter>ro</parameter></paramdef>
   <paramdef>unsigned long <parameter>incompat</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to check.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>compat</parameter></term>
   <listitem>
    <para>
     bitmask of compatible features
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>ro</parameter></term>
   <listitem>
    <para>
     bitmask of features that force read-only mount
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>incompat</parameter></term>
   <listitem>
    <para>
     bitmask of incompatible features
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Check whether the journal uses all of a given set of
   features.  Return true (non-zero) if it does. 
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-check-available-features">journal_check_available_features</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_check_available_features</refname>
 <refpurpose>
      Check feature set in journalling layer
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_check_available_features </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>unsigned long <parameter>compat</parameter></paramdef>
   <paramdef>unsigned long <parameter>ro</parameter></paramdef>
   <paramdef>unsigned long <parameter>incompat</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to check.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>compat</parameter></term>
   <listitem>
    <para>
     bitmask of compatible features
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>ro</parameter></term>
   <listitem>
    <para>
     bitmask of features that force read-only mount
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>incompat</parameter></term>
   <listitem>
    <para>
     bitmask of incompatible features
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Check whether the journaling code supports the use of
   all of a given set of features on this journal.  Return true
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-set-features">journal_set_features</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_set_features</refname>
 <refpurpose>
      Mark a given journal feature in the superblock
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_set_features </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>unsigned long <parameter>compat</parameter></paramdef>
   <paramdef>unsigned long <parameter>ro</parameter></paramdef>
   <paramdef>unsigned long <parameter>incompat</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to act on.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>compat</parameter></term>
   <listitem>
    <para>
     bitmask of compatible features
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>ro</parameter></term>
   <listitem>
    <para>
     bitmask of features that force read-only mount
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>incompat</parameter></term>
   <listitem>
    <para>
     bitmask of incompatible features
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Mark a given journal feature as present on the
   superblock.  Returns true if the requested features could be set. 
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-update-format">journal_update_format</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_update_format</refname>
 <refpurpose>
      Update on-disk journal structure.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_update_format </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to act on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Given an initialised but unloaded journal struct, poke about in the
   on-disk structure to update it to the most recent supported version.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-flush">journal_flush</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_flush</refname>
 <refpurpose>
      Flush journal
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_flush </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to act on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Flush all data for a given journal to disk and empty the journal.
   Filesystems can use this when remounting readonly to ensure that
   recovery does not need to happen on remount.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-wipe">journal_wipe</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_wipe</refname>
 <refpurpose>
      Wipe journal contents
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_wipe </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>int <parameter>write</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to act on.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>write</parameter></term>
   <listitem>
    <para>
     flag (see below)
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Wipe out all of the contents of a journal, safely.  This will produce
   a warning if the journal contains any valid recovery information.
   Must be called between journal_init_*() and <function>journal_load</function>.
   </para><para>

   If 'write' is non-zero, then we wipe out the journal on disk; otherwise
   we merely suppress recovery.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-abort">journal_abort</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_abort</refname>
 <refpurpose>
      Shutdown the journal immediately.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>journal_abort </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>int <parameter>errno</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     the journal to shutdown.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>errno</parameter></term>
   <listitem>
    <para>
       an error number to record in the journal indicating
     the reason for the shutdown.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Perform a complete, immediate shutdown of the ENTIRE
   journal (not of a single transaction).  This operation cannot be
   undone without closing and reopening the journal.
   </para><para>

   The journal_abort function is intended to support higher level error
   recovery mechanisms such as the ext2/ext3 remount-readonly error
   mode.
   </para><para>

   Journal abort has very specific semantics.  Any existing dirty,
   unjournaled buffers in the main filesystem will still be written to
   disk by bdflush, but the journaling mechanism will be suspended
   immediately and no further transaction commits will be honoured.
   </para><para>

   Any dirty, journaled buffers will be written back to disk without
   hitting the journal.  Atomicity cannot be guaranteed on an aborted
   filesystem, but we _do_ attempt to leave as much data as possible
   behind for fsck to use for cleanup.
   </para><para>

   Any attempt to get a new transaction handle on a journal which is in
   ABORT state will just result in an -EROFS error return.  A
   journal_stop on an existing handle will return -EIO if we have
   entered abort state during the update.
   </para><para>

   Recursive transactions are not disturbed by journal abort until the
   final journal_stop, which will receive the -EIO error.
   </para><para>

   Finally, the journal_abort call allows the caller to supply an errno
   which will be recorded (if possible) in the journal superblock.  This
   allows a client to record failure conditions in the middle of a
   transaction without having to complete the transaction to record the
   failure to disk.  ext3_error, for example, now uses this
   functionality.
   </para><para>

   Errors which originate from within the journaling layer will NOT
   supply an errno; a null errno implies that absolutely no further
   writes are done to the journal (unless there are any already in
   progress).
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-errno">journal_errno</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_errno</refname>
 <refpurpose>
      returns the journal's error state.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_errno </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     journal to examine.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   This is the errno numbet set with <function>journal_abort</function>, the last
   time the journal was mounted - if the journal was stopped
   without calling abort this will be 0.
   </para><para>

   If the journal has been aborted on this mount time -EROFS will
   be returned.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-clear-err">journal_clear_err</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_clear_err</refname>
 <refpurpose>
      clears the journal's error state
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_clear_err </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     journal to act on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   An error must be cleared or Acked to take a FS out of readonly
   mode.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-ack-err">journal_ack_err</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_ack_err</refname>
 <refpurpose>
      Ack journal err.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>journal_ack_err </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     journal to act on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   An error must be cleared or Acked to take a FS out of readonly
   mode.
</para>
</refsect1>
</refentry>

<!-- fs/jbd/recovery.c -->
<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-recover">journal_recover</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_recover</refname>
 <refpurpose>
   recovers a on-disk journal
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_recover </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     the journal to recover
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   The primary function for recovering the log contents when mounting a
   journaled device.  
   </para><para>

   Recovery is done in three passes.  In the first pass, we look for the
   end of the log.  In the second, we assemble the list of revoke
   blocks.  In the third and final pass, we replay any un-revoked blocks
   in the log.  
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-skip-recovery">journal_skip_recovery</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_skip_recovery</refname>
 <refpurpose>
      Start journal and wipe exiting records
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_skip_recovery </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     journal to startup
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Locate any valid recovery information from the journal and set up the
   journal structures in memory to ignore it (presumably because the
   caller has evidence that it is out of date).  
   This function does'nt appear to be exorted..
   </para><para>

   We perform one pass over the journal to allow us to tell the user how
   much recovery information is being erased, and to let us initialise
   the journal transaction sequence numbers to the next unused ID. 
</para>
</refsect1>
</refentry>

	</sect1>
	<sect1><title>Transasction Level</title>
<!-- fs/jbd/transaction.c -->
<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-start">journal_start</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_start</refname>
 <refpurpose>
   Obtain a new handle.  
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>handle_t * <function>journal_start </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>int <parameter>nblocks</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     Journal to start transaction on.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>nblocks</parameter></term>
   <listitem>
    <para>
     number of block buffer we might modify
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   We make sure that the transaction can guarantee at least nblocks of
   modified buffers in the log.  We block until the log can guarantee
   that much space.  
   </para><para>

   This function is visible to journal users (like ext3fs), so is not
   called with the journal already locked.
   </para><para>

   Return a pointer to a newly allocated handle, or NULL on failure
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-extend">journal_extend</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_extend</refname>
 <refpurpose>
      extend buffer credits.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_extend </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>int <parameter>nblocks</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
      handle to 'extend'
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>nblocks</parameter></term>
   <listitem>
    <para>
     nr blocks to try to extend by.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Some transactions, such as large extends and truncates, can be done
   atomically all at once or in several stages.  The operation requests
   a credit for a number of buffer modications in advance, but can
   extend its credit if it needs more.  
   </para><para>

   journal_extend tries to give the running handle more buffer credits.
   It does not guarantee that allocation - this is a best-effort only.
   The calling process MUST be able to deal cleanly with a failure to
   extend here.
   </para><para>

   Return 0 on success, non-zero on failure.
   </para><para>

   return code &lt; 0 implies an error
   return code &gt; 0 implies normal transaction-full status.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-restart">journal_restart</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_restart</refname>
 <refpurpose>
      restart a handle .
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_restart </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>int <parameter>nblocks</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
      handle to restart
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>nblocks</parameter></term>
   <listitem>
    <para>
     nr credits requested
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Restart a handle for a multi-transaction filesystem
   operation.
   </para><para>

   If the <function>journal_extend</function> call above fails to grant new buffer credits
   to a running handle, a call to journal_restart will commit the
   handle's transaction so far and reattach the handle to a new
   transaction capabable of guaranteeing the requested number of
   credits.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-lock-updates">journal_lock_updates</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_lock_updates</refname>
 <refpurpose>
      establish a transaction barrier.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>journal_lock_updates </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
      Journal to establish a barrier on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   This locks out any further updates from being started, and blocks
   until all existing updates have completed, returning only once the
   journal is in a quiescent state with no updates running.
   </para><para>

   The journal lock should not be held on entry.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-unlock-updates">journal_unlock_updates</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_unlock_updates</refname>
 <refpurpose>
      release barrier
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>journal_unlock_updates </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
      Journal to release the barrier on.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Release a transaction barrier obtained with <function>journal_lock_updates</function>.
   </para><para>

   Should be called without the journal lock held.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-get-write-access">journal_get_write_access</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_get_write_access</refname>
 <refpurpose>
      notify intent to modify a buffer for metadata (not data) update.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_get_write_access </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>struct buffer_head * <parameter>bh</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
     transaction to add buffer modifications to
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>bh</parameter></term>
   <listitem>
    <para>
         bh to be used for metadata writes
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Returns an error code or 0 on success.
   </para><para>

   In full data journalling mode the buffer may be of type BJ_AsyncData,
   because we're <function>write</function>ing a buffer which is also part of a shared mapping.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-get-create-access">journal_get_create_access</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_get_create_access</refname>
 <refpurpose>
      notify intent to use newly created bh
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_get_create_access </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>struct buffer_head * <parameter>bh</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
     transaction to new buffer to
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>bh</parameter></term>
   <listitem>
    <para>
     new buffer.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Call this if you create a new bh.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-get-undo-access">journal_get_undo_access</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_get_undo_access</refname>
 <refpurpose>
       Notify intent to modify metadata with
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_get_undo_access </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>struct buffer_head * <parameter>bh</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
     transaction
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>bh</parameter></term>
   <listitem>
    <para>
     buffer to undo
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Sometimes there is a need to distinguish between metadata which has
   been committed to disk and that which has not.  The ext3fs code uses
   this for freeing and allocating space, we have to make sure that we
   do not reuse freed space until the deallocation has been committed,
   since if we overwrote that space we would make the delete
   un-rewindable in case of a crash.
   </para><para>

   To deal with that, journal_get_undo_access requests write access to a
   buffer for parts of non-rewindable operations such as delete
   operations on the bitmaps.  The journaling code must keep a copy of
   the buffer's contents prior to the undo_access call until such time
   as we know that the buffer has definitely been committed to disk.
   </para><para>

   We never need to know which transaction the committed data is part
   of, buffers touched here are guaranteed to be dirtied later and so
   will be committed to a new transaction in due course, at which point
   we can discard the old committed data pointer.
   </para><para>

   Returns error number or 0 on success.
</para>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Sometimes there is a need to distinguish between metadata which has
   been committed to disk and that which has not.  The ext3fs code uses
   this for freeing and allocating space, we have to make sure that we
   do not reuse freed space until the deallocation has been committed,
   since if we overwrote that space we would make the delete
   un-rewindable in case of a crash.
   </para><para>

   To deal with that, journal_get_undo_access requests write access to a
   buffer for parts of non-rewindable operations such as delete
   operations on the bitmaps.  The journaling code must keep a copy of
   the buffer's contents prior to the undo_access call until such time
   as we know that the buffer has definitely been committed to disk.
   </para><para>

   We never need to know which transaction the committed data is part
   of, buffers touched here are guaranteed to be dirtied later and so
   will be committed to a new transaction in due course, at which point
   we can discard the old committed data pointer.
   </para><para>

   Returns error number or 0 on success.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-dirty-data">journal_dirty_data</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_dirty_data</refname>
 <refpurpose>
       mark a buffer as containing dirty data which
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_dirty_data </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>struct buffer_head * <parameter>bh</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
     transaction
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>bh</parameter></term>
   <listitem>
    <para>
     bufferhead to mark
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   The buffer is placed on the transaction's data list and is marked as
   belonging to the transaction.
   </para><para>

   Returns error number or 0 on success.
   </para><para>

   <function>journal_dirty_data</function> can be called via page_launder-&gt;ext3_writepage
   by kswapd.
</para>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   The buffer is placed on the transaction's data list and is marked as
   belonging to the transaction.
   </para><para>

   Returns error number or 0 on success.
   </para><para>

   <function>journal_dirty_data</function> can be called via page_launder-&gt;ext3_writepage
   by kswapd.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-dirty-metadata">journal_dirty_metadata</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_dirty_metadata</refname>
 <refpurpose>
       mark a buffer as containing dirty metadata
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_dirty_metadata </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>struct buffer_head * <parameter>bh</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
     transaction to add buffer to.
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>bh</parameter></term>
   <listitem>
    <para>
     buffer to mark 
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   mark dirty metadata which needs to be journaled as part of the current
   transaction.
   </para><para>

   The buffer is placed on the transaction's metadata list and is marked
   as belonging to the transaction.  
   </para><para>

   Returns error number or 0 on success.  
   </para><para>

   Special care needs to be taken if the buffer already belongs to the
   current committing transaction (in which case we should have frozen
   data present for that commit).  In that case, we don't relink the
</para>
</refsect1>
<refsect1>
<title>buffer</title>
<para>
   that only gets done when the old transaction finally
   completes its commit.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-forget">journal_forget</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_forget</refname>
 <refpurpose>
      <function>bforget</function> for potentially-journaled buffers.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_forget </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
   <paramdef>struct buffer_head * <parameter>bh</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
     transaction handle
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>bh</parameter></term>
   <listitem>
    <para>
         bh to 'forget'
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   We can only do the bforget if there are no commits pending against the
   buffer.  If the buffer is dirty in the current running transaction we
   can safely unlink it. 
   </para><para>

   bh may not be a journalled buffer at all - it may be a non-JBD
   buffer which came off the hashtable.  Check for this.
   </para><para>

   Decrements bh-&gt;b_count by one.
   </para><para>

   Allow this call even if the handle has aborted --- it may be part of
   the caller's cleanup after an abort.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-stop">journal_stop</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_stop</refname>
 <refpurpose>
      complete a transaction
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_stop </function></funcdef>
   <paramdef>handle_t * <parameter>handle</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>handle</parameter></term>
   <listitem>
    <para>
     tranaction to complete.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   All done for a particular handle.
   </para><para>

   There is not much action needed here.  We just return any remaining
   buffer credits to the transaction and remove the handle.  The only
   complication is that we need to start a commit operation if the
   filesystem is marked for synchronous update.
   </para><para>

   journal_stop itself will not usually return an error, but it may
   do so in unusual circumstances.  In particular, expect it to 
   return -EIO if a journal_abort has been executed since the
   transaction began.
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-try-to-free-buffers">journal_try_to_free_buffers</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_try_to_free_buffers</refname>
 <refpurpose>
      try to free page buffers.
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>journal_try_to_free_buffers </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>struct page * <parameter>page</parameter></paramdef>
   <paramdef>gfp_t <parameter>unused_gfp_mask</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     journal for operation
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>page</parameter></term>
   <listitem>
    <para>
     to try and free
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>unused_gfp_mask</parameter></term>
   <listitem>
    <para>
     unused
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   </para><para>

   For all the buffers on this page,
   if they are fully written out ordered data, move them onto BUF_CLEAN
   so <function>try_to_free_buffers</function> can reap them.
   </para><para>

   This function returns non-zero if we wish <function>try_to_free_buffers</function>
   to be called. We do this if the page is releasable by <function>try_to_free_buffers</function>.
   We also do it if the page has locked or dirty buffers and the caller wants
   us to perform sync or async writeout.
   </para><para>

   This complicates JBD locking somewhat.  We aren't protected by the
   BKL here.  We wish to remove the buffer from its committing or
   running transaction's -&gt;t_datalist via __journal_unfile_buffer.
   </para><para>

   This may *change* the value of transaction_t-&gt;t_datalist, so anyone
   who looks at t_datalist needs to lock against this function.
   </para><para>

   Even worse, someone may be doing a journal_dirty_data on this
   buffer.  So we need to lock against that.  <function>journal_dirty_data</function>
   will come out of the lock with the buffer dirty, which makes it
   ineligible for release here.
   </para><para>

   Who else is affected by this?  hmm...  Really the only contender
   is <function>do_get_write_access</function> - it could be looking at the buffer while
   <function>journal_try_to_free_buffer</function> is changing its state.  But that
   cannot happen because we never reallocate freed data as metadata
   while the data is part of a transaction.  Yes?
</para>
</refsect1>
</refentry>

<refentry>
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>November 2007</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase id="API-journal-invalidatepage">journal_invalidatepage</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
</refmeta>
<refnamediv>
 <refname>journal_invalidatepage</refname>
 <refpurpose>
   </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>journal_invalidatepage </function></funcdef>
   <paramdef>journal_t * <parameter>journal</parameter></paramdef>
   <paramdef>struct page * <parameter>page</parameter></paramdef>
   <paramdef>unsigned long <parameter>offset</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>journal</parameter></term>
   <listitem>
    <para>
     journal to use for flush... 
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>page</parameter></term>
   <listitem>
    <para>
        page to flush
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>offset</parameter></term>
   <listitem>
    <para>
      length of page to invalidate.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Reap page buffers containing data after offset in page.
</para>
</refsect1>
</refentry>

	</sect1>
</chapter>
<chapter>
     <title>See also</title>
	<para>
	<citation>
	   <ulink url="ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/journal-design.ps.gz">
	   	Journaling the Linux ext2fs Filesystem,LinuxExpo 98, Stephen Tweedie
	   </ulink>
	   </citation>
	   </para>
	   <para>
	   <citation>
	   <ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html">
	   	Ext3 Journalling FileSystem , OLS 2000, Dr. Stephen Tweedie
	   </ulink>
	   </citation>
	   </para>
</chapter>

</book>
