Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 17: Data Synchronization


17.7.2 Writeback Control


A second data structure holds the various parametersthat control writeback of dirty pages. Upper layers
use it to pass information about how writeback is to be performed to the lower layers (top to bottom
in Figure 17-1). However, the structure also allowsfor propagating status information in the reverse
direction (bottom to top):

<writeback.h>
/* A control structure which tells the writeback code what to do. */
struct writeback_control {
struct backing_dev_info *bdi; /* If !NULL, only write back this
queue */
enum writeback_sync_modes sync_mode;
unsigned long *older_than_this; /* If !NULL, only write back inodes
older than this */
long nr_to_write; /* Write this many pages, and decrement
this for each page written */
long pages_skipped; /* Pages which were not written */

loff_t range_start;
loff_t range_end;

unsigned nonblocking:1; /* Don’t get stuck on request queues */
unsigned encountered_congestion:1; /* An output: a queue is full */
unsigned for_kupdate:1; /* A kupdate writeback */
unsigned for_reclaim:1; /* Invoked from the page allocator */
unsigned for_writepages:1; /* This is a writepages() call */
unsigned range_cyclic:1; /* range_start is cyclic */
};

The meanings of the structure elements are as follows:

❑ bdipoints to a structure of typebacking_dev_info, which summarizes information on
the underlying storage medium. This structure is discussed briefly in Chapter 16. Two
things interest us here. First, the structure provides a variable to hold the status of the
writeback queue (this means, e.g., that congestion can be signaled if there are too many
write requests), and second, it allows RAM-based filesystems that do not have a (block
device) backing store to be labeled — writeback operations to systems of this kind make
no sense.
❑ sync_modedistinguishes between three different synchronization modes:
<writeback.h>
enum writeback_sync_modes {
WB_SYNC_NONE, /* Don’t wait on anything */
WB_SYNC_ALL, /* Wait on every mapping */
WB_SYNC_HOLD, /* Hold the inode on sb_dirty for sys_sync() */
};

To synchronize data, the kernel needs to pass a corresponding write request to the underlying
block device. Requests to block devices are asynchronous by nature. If the kernel wants to ensure
that the data have safely reached the device, it needs to wait for completion after the request has
been issued. This behavior is mandated withWB_SYNC_ALL. Waiting for writeback to complete is
Free download pdf