asmlinkage long sys_fsync(unsigned int fd) {

asmlinkage long sys_fdatasync(unsigned int fd) {

The code flow diagram for the common function_do_fsync is shown in Figure 17-12.

Figure 17-12: Code flow diagram for _do_sync.

Synchronization of a single file is relatively straightforward. fget is used to find the appropriate file instance by reference to the file descriptor, and then work is delegated to three functions:

1. filemap_fdatawrite (via a detour over_filemap_fdatawrite and_filemap_

fdatawrite_range) first generates a writeback_control instance whose nr_to_write value (maximum number of pages to be flushed) is set to double the number of pages of the mapping to ensure that all pages are written back. Afterward, the familiar do_writepages method invokes the low-level write routines of the filesystem in which the file is located.

2. The filesystem-dependent fsync function found using the file_operations structure of the file is then invoked to write back the cached file data. This is where fsync and fdatasync differ — fsync has a parameter to specify whether metadata are also to be flushed as well as the regular caches. The parameter is set to 0 for fsync and to 1 for fdatasync.

3. Synchronization is then concluded by invoking filemap_fdatawait to wait for the end of the write operation initiated in filemap_fdatawrite. This ensures that the asynchronous write operations appear as synchronous to the user application because the system call does not return control to userspace until writeback of the desired data has been completed in the view of both the block layer and the filesystem layer.

The methods provided for file_operations->fsync are very similar for most filesystems. Figure 17-13 shows the code flow diagram for a generalized method.


- sync_mapping_buffers I





Figure 17-13: Code flow diagram for f_op->fsync.

The code performs two tasks:

1. sync_mapping_buffers writes back all private inode buffers in the private_list of the mapping instance. These normally hold indirection blocks or other internal filesystem data that are not part of the inode management data but are used to manage the data themselves.

This function delegates work to fsync_mapping_buffers, which iterates over all buffers. The buffer data are written to the block layer by the ll_rw_block function with which you are familiar from Chapter 6. With the help of osync_buffers_list, the kernel then waits until the write operations have been completed (the block layer also buffers write accesses) and then ensures that synchronization of the associated metadata outside sync_buffers_list appears as a synchronous operation.

2. fs_sync_inode writes back the inode management data (i.e., the data held directly in the filesystem-specific inode structure). Note that the datasync argument of fsync must be set to (0) to invoke the method. This is the one and only difference between fdatasync and fsync.

Since writeback of inode management data is filesystem-specific, see Chapter 9.

Continue reading here: Mmmsyncc

Was this article helpful?

0 0