Skip to content

Commit

Permalink
nilfs2: flush disk caches in syncing
Browse files Browse the repository at this point in the history
There are two cases that the cache flush is needed to avoid data loss
against unexpected hang or power failure.  One is sync file function (i.e.
 nilfs_sync_file) and another is checkpointing ioctl.

This issues a cache flush request to device for such cases if barrier
mount option is enabled, and makes sure data really is on persistent
storage on their completion.

Signed-off-by: Ryusuke Konishi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
konis authored and torvalds committed Jun 1, 2012
1 parent a1d4944 commit 1147597
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
24 changes: 14 additions & 10 deletions fs/nilfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
* This function should be implemented when the writeback function
* will be implemented.
*/
struct the_nilfs *nilfs;
struct inode *inode = file->f_mapping->host;
int err;

Expand All @@ -45,18 +46,21 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
return err;
mutex_lock(&inode->i_mutex);

if (!nilfs_inode_dirty(inode)) {
mutex_unlock(&inode->i_mutex);
return 0;
if (nilfs_inode_dirty(inode)) {
if (datasync)
err = nilfs_construct_dsync_segment(inode->i_sb, inode,
0, LLONG_MAX);
else
err = nilfs_construct_segment(inode->i_sb);
}

if (datasync)
err = nilfs_construct_dsync_segment(inode->i_sb, inode, 0,
LLONG_MAX);
else
err = nilfs_construct_segment(inode->i_sb);

mutex_unlock(&inode->i_mutex);

nilfs = inode->i_sb->s_fs_info;
if (!err && nilfs_test_opt(nilfs, BARRIER)) {
err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
if (err != -EIO)
err = 0;
}
return err;
}

Expand Down
8 changes: 7 additions & 1 deletion fs/nilfs2/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,14 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
if (ret < 0)
return ret;

nilfs = inode->i_sb->s_fs_info;
if (nilfs_test_opt(nilfs, BARRIER)) {
ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
if (ret == -EIO)
return ret;
}

if (argp != NULL) {
nilfs = inode->i_sb->s_fs_info;
down_read(&nilfs->ns_segctor_sem);
cno = nilfs->ns_cno - 1;
up_read(&nilfs->ns_segctor_sem);
Expand Down

0 comments on commit 1147597

Please sign in to comment.