aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2012-05-31 19:26:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 20:49:27 -0400
commit11475975dd3c0a8e639f1544ef6530373de5979e (patch)
treee20344e3d296d2271eea093c76fa728e1c341510 /fs
parenta1d494495c69ef0810cd008f59310d2b9db28e36 (diff)
nilfs2: flush disk caches in syncing
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 <konishi.ryusuke@lab.ntt.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/nilfs2/file.c24
-rw-r--r--fs/nilfs2/ioctl.c8
2 files changed, 21 insertions, 11 deletions
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 26601529dc17..62cebc8e1a1f 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -37,6 +37,7 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
37 * This function should be implemented when the writeback function 37 * This function should be implemented when the writeback function
38 * will be implemented. 38 * will be implemented.
39 */ 39 */
40 struct the_nilfs *nilfs;
40 struct inode *inode = file->f_mapping->host; 41 struct inode *inode = file->f_mapping->host;
41 int err; 42 int err;
42 43
@@ -45,18 +46,21 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
45 return err; 46 return err;
46 mutex_lock(&inode->i_mutex); 47 mutex_lock(&inode->i_mutex);
47 48
48 if (!nilfs_inode_dirty(inode)) { 49 if (nilfs_inode_dirty(inode)) {
49 mutex_unlock(&inode->i_mutex); 50 if (datasync)
50 return 0; 51 err = nilfs_construct_dsync_segment(inode->i_sb, inode,
52 0, LLONG_MAX);
53 else
54 err = nilfs_construct_segment(inode->i_sb);
51 } 55 }
52
53 if (datasync)
54 err = nilfs_construct_dsync_segment(inode->i_sb, inode, 0,
55 LLONG_MAX);
56 else
57 err = nilfs_construct_segment(inode->i_sb);
58
59 mutex_unlock(&inode->i_mutex); 56 mutex_unlock(&inode->i_mutex);
57
58 nilfs = inode->i_sb->s_fs_info;
59 if (!err && nilfs_test_opt(nilfs, BARRIER)) {
60 err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
61 if (err != -EIO)
62 err = 0;
63 }
60 return err; 64 return err;
61} 65}
62 66
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 2a70fce70c65..06658caa18bd 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -692,8 +692,14 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
692 if (ret < 0) 692 if (ret < 0)
693 return ret; 693 return ret;
694 694
695 nilfs = inode->i_sb->s_fs_info;
696 if (nilfs_test_opt(nilfs, BARRIER)) {
697 ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
698 if (ret == -EIO)
699 return ret;
700 }
701
695 if (argp != NULL) { 702 if (argp != NULL) {
696 nilfs = inode->i_sb->s_fs_info;
697 down_read(&nilfs->ns_segctor_sem); 703 down_read(&nilfs->ns_segctor_sem);
698 cno = nilfs->ns_cno - 1; 704 cno = nilfs->ns_cno - 1;
699 up_read(&nilfs->ns_segctor_sem); 705 up_read(&nilfs->ns_segctor_sem);