summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/wapbl.9 3.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man9/wapbl.9 3.html')
-rw-r--r--static/netbsd/man9/wapbl.9 3.html424
1 files changed, 0 insertions, 424 deletions
diff --git a/static/netbsd/man9/wapbl.9 3.html b/static/netbsd/man9/wapbl.9 3.html
deleted file mode 100644
index 241ea757..00000000
--- a/static/netbsd/man9/wapbl.9 3.html
+++ /dev/null
@@ -1,424 +0,0 @@
-<table class="head">
- <tr>
- <td class="head-ltitle">WAPBL(9)</td>
- <td class="head-vol">Kernel Developer's Manual</td>
- <td class="head-rtitle">WAPBL(9)</td>
- </tr>
-</table>
-<div class="manual-text">
-<section class="Sh">
-<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
-<p class="Pp"><code class="Nm">WAPBL</code>,
- <code class="Nm">wapbl_start</code>, <code class="Nm">wapbl_stop</code>,
- <code class="Nm">wapbl_begin</code>, <code class="Nm">wapbl_end</code>,
- <code class="Nm">wapbl_flush</code>, <code class="Nm">wapbl_discard</code>,
- <code class="Nm">wapbl_add_buf</code>,
- <code class="Nm">wapbl_remove_buf</code>,
- <code class="Nm">wapbl_resize_buf</code>,
- <code class="Nm">wapbl_register_inode</code>,
- <code class="Nm">wapbl_unregister_inode</code>,
- <code class="Nm">wapbl_register_deallocation</code>,
- <code class="Nm">wapbl_jlock_assert</code>,
- <code class="Nm">wapbl_junlock_assert</code> &#x2014;
- <span class="Nd">write-ahead physical block logging for file
- systems</span></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
-<p class="Pp"><code class="In">#include
- &lt;<a class="In">sys/wapbl.h</a>&gt;</code></p>
-<p class="Pp"><var class="Vt">typedef void (*wapbl_flush_fn_t)(struct mount *,
- daddr_t *, int *, int)</var>;</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">wapbl_start</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl **wlp</var>, <var class="Fa" style="white-space: nowrap;">struct mount
- *mp</var>, <var class="Fa" style="white-space: nowrap;">struct vnode
- *devvp</var>, <var class="Fa" style="white-space: nowrap;">daddr_t
- off</var>, <var class="Fa" style="white-space: nowrap;">size_t count</var>,
- <var class="Fa" style="white-space: nowrap;">size_t blksize</var>,
- <var class="Fa" style="white-space: nowrap;">struct wapbl_replay *wr</var>,
- <var class="Fa" style="white-space: nowrap;">wapbl_flush_fn_t flushfn</var>,
- <var class="Fa" style="white-space: nowrap;">wapbl_flush_fn_t
- flushabortfn</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">wapbl_stop</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">int
- force</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">wapbl_begin</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">const char
- *file</var>, <var class="Fa" style="white-space: nowrap;">int
- line</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_end</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">wapbl_flush</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">int
- wait</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_discard</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_add_buf</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">struct buf
- *bp</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_remove_buf</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">struct buf
- *bp</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_resize_buf</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">struct buf
- *bp</var>, <var class="Fa" style="white-space: nowrap;">long oldsz</var>,
- <var class="Fa" style="white-space: nowrap;">long oldcnt</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_register_inode</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">ino_t
- ino</var>, <var class="Fa" style="white-space: nowrap;">mode_t
- mode</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_unregister_inode</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">ino_t
- ino</var>, <var class="Fa" style="white-space: nowrap;">mode_t
- mode</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_register_deallocation</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>, <var class="Fa" style="white-space: nowrap;">daddr_t
- blk</var>, <var class="Fa" style="white-space: nowrap;">int len</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_jlock_assert</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">wapbl_junlock_assert</code>(<var class="Fa" style="white-space: nowrap;">struct
- wapbl *wl</var>);</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
-<p class="Pp"><code class="Nm">WAPBL</code>, or
- <a class="permalink" href="#write-ahead"><i class="Em" id="write-ahead">write-ahead
- physical block logging</i></a>, is an abstraction for file systems to write
- physical blocks in the <a class="Xr">buffercache(9)</a> to a bounded-size
- log first before their real destinations on disk. The name means:</p>
-<div class="Bd-indent">
-<dl class="Bl-tag">
- <dt>logging</dt>
- <dd>batches of writes are issued atomically via a log</dd>
- <dt>physical block</dt>
- <dd>only physical blocks, not logical file system operations, are stored in
- the log</dd>
- <dt>write-ahead</dt>
- <dd>before writing a block to disk, its new content, rather than its old
- content for roll-back, is recorded in the log</dd>
-</dl>
-</div>
-<p class="Pp" id="transactions">When a file system using
- <code class="Nm">WAPBL</code> issues writes (as in
- <a class="Xr">bwrite(9)</a> or <a class="Xr">bdwrite(9)</a>), they are
- grouped in batches called
- <a class="permalink" href="#transactions"><i class="Em">transactions</i></a>
- in memory, which are serialized to be consistent with program order before
- <code class="Nm">WAPBL</code> submits them to disk atomically.</p>
-<p class="Pp">Thus, within a transaction, after one write, another write need
- not wait for disk I/O, and if the system is interrupted, e.g. by a crash or
- by power failure, either both writes will appear on disk, or neither
- will.</p>
-<p class="Pp" id="log">When a transaction is full, it is written to a circular
- buffer on disk called the
- <a class="permalink" href="#log"><i class="Em">log</i></a>. When the
- transaction has been written to disk, every write in the transaction is
- submitted to disk asynchronously. Finally, the file system may issue new
- writes via <code class="Nm">WAPBL</code> once enough writes submitted to
- disk have completed.</p>
-<p class="Pp">After interruption, such as a crash or power failure, some writes
- issued by the file system may not have completed. However, the log is
- written consistently with program order and before file system writes are
- submitted to disk. Hence a consistent program-order view of the file system
- can be attained by resubmitting the writes that were successfully stored in
- the log using <a class="Xr">wapbl_replay(9)</a>. This may not be the same
- state just before interruption &#x2014; writes in transactions that did not
- reach the disk will be excluded.</p>
-<p class="Pp" id="wapbl_start">For a file system to use
- <code class="Nm">WAPBL</code>, its <a class="Xr">VFS_MOUNT(9)</a> method
- should first replay any journal on disk using
- <a class="Xr">wapbl_replay(9)</a>, and then, if the mount is read/write,
- initialize <code class="Nm">WAPBL</code> for the mount by calling
- <a class="permalink" href="#wapbl_start"><code class="Fn">wapbl_start</code></a>().
- The <a class="Xr">VFS_UNMOUNT(9)</a> method should call
- <a class="permalink" href="#wapbl_stop"><code class="Fn" id="wapbl_stop">wapbl_stop</code></a>().</p>
-<p class="Pp" id="wapbl_begin">Before issuing any
- <a class="Xr">buffercache(9)</a> writes, the file system must acquire a
- shared lock on the current <code class="Nm">WAPBL</code> transaction with
- <a class="permalink" href="#wapbl_begin"><code class="Fn">wapbl_begin</code></a>(),
- which may sleep until there is room in the transaction for new writes. After
- issuing the writes, the file system must release its shared lock on the
- transaction with <code class="Fn">wapbl_end</code>(). Either all writes
- issued between <code class="Fn">wapbl_begin</code>() and
- <code class="Fn">wapbl_end</code>() will complete, or none of them will.</p>
-<p class="Pp" id="exclusive">File systems may also witness an
- <a class="permalink" href="#exclusive"><i class="Em">exclusive</i></a> lock
- on the current transaction when <code class="Nm">WAPBL</code> is flushing
- the transaction to disk, or aborting a flush, and invokes a file system's
- callback. File systems can assert that the transaction is locked with
- <a class="permalink" href="#wapbl_jlock_assert"><code class="Fn" id="wapbl_jlock_assert">wapbl_jlock_assert</code></a>(),
- or not
- <a class="permalink" href="#exclusively"><i class="Em" id="exclusively">exclusively</i></a>
- locked, with <code class="Fn">wapbl_junlock_assert</code>().</p>
-<p class="Pp" id="wapbl_register_inode">If a file system requires multiple
- transactions to initialize an inode, and needs to destroy partially
- initialized inodes during replay, it can register them by
- <var class="Vt">ino_t</var> inode number before initialization with
- <a class="permalink" href="#wapbl_register_inode"><code class="Fn">wapbl_register_inode</code></a>()
- and unregister them with
- <a class="permalink" href="#wapbl_unregister_inode"><code class="Fn" id="wapbl_unregister_inode">wapbl_unregister_inode</code></a>()
- once initialization is complete. <code class="Nm">WAPBL</code> does not
- actually concern itself whether the objects identified by
- <var class="Vt">ino_t</var> values are &#x2018;inodes&#x2019; or
- &#x2018;quaggas&#x2019; or anything else &#x2014; file systems may use this
- to list any objects keyed by <var class="Vt">ino_t</var> value in the
- log.</p>
-<p class="Pp">When a file system frees resources on disk and issues writes to
- reflect the fact, it cannot then reuse the resources until the writes have
- reached the disk. However, as far as the <a class="Xr">buffercache(9)</a> is
- concerned, as soon as the file system issues the writes, they will appear to
- have been written. So the file system must not attempt to reuse the resource
- until the current <code class="Nm">WAPBL</code> transaction has been flushed
- to disk.</p>
-<p class="Pp" id="wapbl_register_deallocation">The file system can defer freeing
- a resource by calling
- <a class="permalink" href="#wapbl_register_deallocation"><code class="Fn">wapbl_register_deallocation</code></a>()
- to record the disk address of the resource and length in bytes of the
- resource. Then, when <code class="Nm">WAPBL</code> next flushes the
- transaction to disk, it will pass an array of the disk addresses and lengths
- in bytes to a file-system-supplied callback. (Again,
- <code class="Nm">WAPBL</code> does not care whether the &#x2018;disk
- address&#x2019; or &#x2018;length in bytes&#x2019; is actually that; it will
- pass along <var class="Vt">daddr_t</var> and <var class="Vt">int</var>
- values.)</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="FUNCTIONS"><a class="permalink" href="#FUNCTIONS">FUNCTIONS</a></h1>
-<dl class="Bl-tag">
- <dt><code class="Fn">wapbl_start</code>(<var class="Fa">wlp</var>,
- <var class="Fa">mp</var>, <var class="Fa">devvp</var>,
- <var class="Fa">off</var>, <var class="Fa">count</var>,
- <var class="Fa">blksize</var>, <var class="Fa">wr</var>,
- <var class="Fa">flushfn</var>, <var class="Fa">flushabortfn</var>)</dt>
- <dd>Start using <code class="Nm">WAPBL</code> for the file system mounted at
- <var class="Fa">mp</var>, storing a log of <var class="Fa">count</var>
- disk sectors at disk address <var class="Fa">off</var> on the block device
- <var class="Fa">devvp</var> writing blocks in units of
- <var class="Fa">blksize</var> bytes. On success, stores an opaque
- <var class="Vt">struct wapbl *</var> cookie in
- <code class="Li">*</code><var class="Fa">wlp</var> for use with the other
- <code class="Nm">WAPBL</code> routines and returns zero. On failure,
- returns an error number.
- <p class="Pp" id="wapbl_start~2">If the file system had replayed the log
- with <a class="Xr">wapbl_replay(9)</a>, then <var class="Fa">wr</var>
- must be the <var class="Vt">struct wapbl_replay *</var> cookie used to
- replay it, and
- <a class="permalink" href="#wapbl_start~2"><code class="Fn">wapbl_start</code></a>()
- will register any inodes that were in the log as if with
- <code class="Fn">wapbl_register_inode</code>(); otherwise
- <var class="Fa">wr</var> must be <code class="Dv">NULL</code>.</p>
- <p class="Pp" id="wapbl_start~3"><var class="Fa">flushfn</var> is a callback
- that <code class="Nm">WAPBL</code> will invoke as
- <var class="Fa">flushfn</var> (<var class="Fa">mp</var>,
- <var class="Fa">deallocblks</var>, <var class="Fa">dealloclens</var>,
- <var class="Fa">dealloccnt</var>) just before it flushes a transaction
- to disk, with the an exclusive lock held on the transaction, where
- <var class="Fa">mp</var> is the mount point passed to
- <a class="permalink" href="#wapbl_start~3"><code class="Fn">wapbl_start</code></a>(),
- <var class="Fa">deallocblks</var> is an array of
- <var class="Fa">dealloccnt</var> disk addresses, and
- <var class="Fa">dealloclens</var> is an array of
- <var class="Fa">dealloccnt</var> lengths, corresponding to the addresses
- and lengths the file system passed to
- <code class="Fn">wapbl_register_deallocation</code>(). If flushing the
- transaction to disk fails, <code class="Nm">WAPBL</code> will call
- <var class="Fa">flushabortfn</var> with the same arguments to undo any
- effects that <var class="Fa">flushfn</var> had.</p>
- </dd>
- <dt><code class="Fn">wapbl_stop</code>(<var class="Fa">wl</var>,
- <var class="Fa">force</var>)</dt>
- <dd>Flush the current transaction to disk and stop using
- <code class="Nm">WAPBL</code>. If flushing the transaction fails and
- <var class="Fa">force</var> is zero, return error. If flushing the
- transaction fails and <var class="Fa">force</var> is nonzero, discard the
- transaction, permanently losing any writes in it. If flushing the
- transaction is successful or if <var class="Fa">force</var> is nonzero,
- free memory associated with <var class="Fa">wl</var> and return zero.</dd>
- <dt><code class="Fn">wapbl_begin</code>(<var class="Fa">wl</var>,
- <var class="Fa">file</var>, <var class="Fa">line</var>)</dt>
- <dd>Wait for space in the current transaction for new writes, flushing it if
- necessary, and acquire a shared lock on it.
- <p class="Pp">The lock is not exclusive: other threads may acquire shared
- locks on the transaction too. The lock is not recursive: a thread may
- not acquire it again without calling <var class="Fa">wapbl_end</var>
- first.</p>
- <p class="Pp">May sleep.</p>
- <p class="Pp"><var class="Fa">file</var> and <var class="Fa">line</var> are
- the file name and line number of the caller for debugging purposes.</p>
- </dd>
- <dt id="wapbl_end"><a class="permalink" href="#wapbl_end"><code class="Fn">wapbl_end</code></a>(<var class="Fa">wl</var>)</dt>
- <dd>Release a shared lock on the transaction acquired with
- <code class="Fn">wapbl_begin</code>().</dd>
- <dt id="wapbl_flush"><a class="permalink" href="#wapbl_flush"><code class="Fn">wapbl_flush</code></a>(<var class="Fa">wl</var>,
- <var class="Fa">wait</var>)</dt>
- <dd>Flush the current transaction to disk. If <var class="Fa">wait</var> is
- nonzero, wait for all writes in the current transaction to complete.
- <p class="Pp">The current transaction must not be locked.</p>
- </dd>
- <dt id="wapbl_discard"><a class="permalink" href="#wapbl_discard"><code class="Fn">wapbl_discard</code></a>(<var class="Fa">wl</var>)</dt>
- <dd>Discard the current transaction, permanently losing any writes in it.
- <p class="Pp">The current transaction must not be locked.</p>
- </dd>
- <dt id="wapbl_add_buf"><a class="permalink" href="#wapbl_add_buf"><code class="Fn">wapbl_add_buf</code></a>(<var class="Fa">wl</var>,
- <var class="Fa">bp</var>)</dt>
- <dd>Add the buffer <var class="Fa">bp</var> to the current transaction, which
- must be locked, because someone has asked to write it.
- <p class="Pp">This is meant to be called from within
- <a class="Xr">buffercache(9)</a>, not by file systems directly.</p>
- </dd>
- <dt id="wapbl_remove_buf"><a class="permalink" href="#wapbl_remove_buf"><code class="Fn">wapbl_remove_buf</code></a>(<var class="Fa">wl</var>,
- <var class="Fa">bp</var>)</dt>
- <dd>Remove the buffer <var class="Fa">bp</var>, which must have been added
- using <var class="Fa">wapbl_add_buf</var>, from the current transaction,
- which must be locked, because it has been invalidated (or XXX ???).
- <p class="Pp">This is meant to be called from within
- <a class="Xr">buffercache(9)</a>, not by file systems directly.</p>
- </dd>
- <dt id="wapbl_resize_buf"><a class="permalink" href="#wapbl_resize_buf"><code class="Fn">wapbl_resize_buf</code></a>(<var class="Fa">wl</var>,
- <var class="Fa">bp</var>, <var class="Fa">oldsz</var>,
- <var class="Fa">oldcnt</var>)</dt>
- <dd>Note that the buffer <var class="Fa">bp</var>, which must have been added
- using <var class="Fa">wapbl_add_buf</var>, has changed size, where
- <var class="Fa">oldsz</var> is the previous allocated size in bytes and
- <var class="Fa">oldcnt</var> is the previous number of valid bytes in
- <var class="Fa">bp</var>.
- <p class="Pp">This is meant to be called from within
- <a class="Xr">buffercache(9)</a>, not by file systems directly.</p>
- </dd>
- <dt id="wapbl_register_inode~2"><a class="permalink" href="#wapbl_register_inode~2"><code class="Fn">wapbl_register_inode</code></a>(<var class="Fa">wl</var>,
- <var class="Fa">ino</var>, <var class="Fa">mode</var>)</dt>
- <dd>Register <var class="Fa">ino</var> with the mode
- <var class="Fa">mode</var> as commencing initialization.</dd>
- <dt id="wapbl_unregister_inode~2"><a class="permalink" href="#wapbl_unregister_inode~2"><code class="Fn">wapbl_unregister_inode</code></a>(<var class="Fa">wl</var>,
- <var class="Fa">ino</var>, <var class="Fa">mode</var>)</dt>
- <dd>Unregister <var class="Fa">ino</var>, which must have previously been
- registered with <var class="Fa">wapbl_register_inode</var> using the same
- <var class="Fa">mode</var>, now that its initialization has
- completed.</dd>
- <dt><code class="Fn">wapbl_register_deallocation</code>(<var class="Fa">wl</var>,
- <var class="Fa">blk</var>, <var class="Fa">len</var>)</dt>
- <dd>Register <var class="Fa">len</var> bytes at the disk address
- <var class="Fa">blk</var> as ready for deallocation, so that they will be
- passed to the <var class="Fa">flushfn</var> that was given to
- <code class="Fn">wapbl_start</code>().</dd>
- <dt><code class="Fn">wapbl_jlock_assert</code>(<var class="Fa">wl</var>)</dt>
- <dd>Assert that the current transaction is locked.
- <p class="Pp" id="any">Note that it might not be locked by the current
- thread: this assertion passes if
- <a class="permalink" href="#any"><i class="Em">any</i></a> thread has it
- locked.</p>
- </dd>
- <dt id="wapbl_junlock_assert"><a class="permalink" href="#wapbl_junlock_assert"><code class="Fn">wapbl_junlock_assert</code></a>(<var class="Fa">wl</var>)</dt>
- <dd>Assert that the current transaction is not exclusively locked by the
- current thread.
- <p class="Pp" id="wapbl_start~4">Users of <code class="Nm">WAPBL</code>
- observe exclusive locks only in the <var class="Fa">flushfn</var> and
- <var class="Fa">flushabortfn</var> callbacks to
- <a class="permalink" href="#wapbl_start~4"><code class="Fn">wapbl_start</code></a>().
- Outside of such contexts, the transaction is never exclusively locked,
- even between <code class="Fn">wapbl_begin</code>() and
- <code class="Fn">wapbl_end</code>().</p>
- <p class="Pp" id="wapbl_begin~2">There is no way to assert that the current
- transaction is not locked at all &#x2014; i.e., that the caller may
- acquire a shared lock on the transaction with
- <a class="permalink" href="#wapbl_begin~2"><code class="Fn">wapbl_begin</code></a>()
- without danger of deadlock.</p>
- </dd>
-</dl>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="CODE_REFERENCES"><a class="permalink" href="#CODE_REFERENCES">CODE
- REFERENCES</a></h1>
-<p class="Pp">The <code class="Nm">WAPBL</code> subsystem is implemented in
- <span class="Pa">sys/kern/vfs_wapbl.c</span>, with hooks in
- <span class="Pa">sys/kern/vfs_bio.c</span>.</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
- ALSO</a></h1>
-<p class="Pp"><a class="Xr">buffercache(9)</a>, <a class="Xr">vfsops(9)</a>,
- <a class="Xr">wapbl_replay(9)</a></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="BUGS"><a class="permalink" href="#BUGS">BUGS</a></h1>
-<p class="Pp"><code class="Nm">WAPBL</code> works only for file system metadata
- managed via the <a class="Xr">buffercache(9)</a>, and provides no way to log
- writes via the page cache, as in <a class="Xr">VOP_GETPAGES(9)</a>,
- <a class="Xr">VOP_PUTPAGES(9)</a>, and <a class="Xr">ubc_uiomove(9)</a>,
- which is normally used for file data.</p>
-<p class="Pp">Not only is <code class="Nm">WAPBL</code> unable to log writes via
- the page cache, it is also unable to defer <a class="Xr">buffercache(9)</a>
- writes until cached pages have been written. This manifests as the
- well-known garbage-data-appended-after-crash bug in FFS: when appending to a
- file, the pages containing new data may not reach the disk before the inode
- update reporting its new size. After a crash, the inode update will be on
- disk, but the new data will not be &#x2014; instead, whatever garbage data
- in the free space will appear to have been appended to the file.
- <code class="Nm">WAPBL</code> exacerbates the problem by increasing the
- throughput of metadata writes, because it can issue many metadata writes
- asynchronously that FFS without <code class="Nm">WAPBL</code> would need to
- issue synchronously in order for <a class="Xr">fsck(8)</a> to work.</p>
-<p class="Pp">The criteria for when the transaction must be flushed to disk
- before <code class="Fn">wapbl_begin</code>() returns are heuristic, i.e.
- wrong. There is no way for a file system to communicate to
- <code class="Fn">wapbl_begin</code>() how many buffers, inodes, and
- deallocations it will issue via <code class="Nm">WAPBL</code> in the
- transaction.</p>
-<p class="Pp"><code class="Nm">WAPBL</code> mainly supports write-ahead, and has
- only limited support for rolling back operations, in the form of
- <code class="Fn">wapbl_register_inode</code>() and
- <code class="Fn">wapbl_unregister_inode</code>(). Consequently, for example,
- large writes appending to a file, which requires multiple disk block
- allocations and an inode update, must occur in a single transaction &#x2014;
- there is no way to roll back the disk block allocations if the write fails
- in the middle, e.g. because of a fault in the middle of the user buffer.</p>
-<p class="Pp"><code class="Fn">wapbl_jlock_assert</code>() does not guarantee
- that the current thread has the current transaction locked.
- <code class="Fn">wapbl_junlock_assert</code>() does not guarantee that the
- current thread does not have the current transaction locked at all.</p>
-<p class="Pp">There is only one <code class="Nm">WAPBL</code> transaction for
- each file system at any given time, and only one
- <code class="Nm">WAPBL</code> log on disk. Consequently, all writes are
- serialized. Extending <code class="Nm">WAPBL</code> to support multiple logs
- per file system, partitioned according to an appropriate scheme, is left as
- an exercise for the reader.</p>
-<p class="Pp">There is no reason for <code class="Nm">WAPBL</code> to require
- its own hooks in <a class="Xr">buffercache(9)</a>.</p>
-<p class="Pp">The on-disk format used by <code class="Nm">WAPBL</code> is
- undocumented.</p>
-</section>
-</div>
-<table class="foot">
- <tr>
- <td class="foot-date">March 26, 2015</td>
- <td class="foot-os">NetBSD 10.1</td>
- </tr>
-</table>