aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sync.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-07-03 10:45:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-22 15:58:49 -0400
commita8c7176b6ded413d5044a00f1d05477b95a6d7ad (patch)
treea2b3e075b7181ac100b13a4f9b57ae6628407a5f /fs/sync.c
parent5c0d6b60a0ba46d45020547eacf7199171920935 (diff)
vfs: Make sys_sync writeout also block device inodes
In case block device does not have filesystem mounted on it, sys_sync will just ignore it and doesn't writeout its dirty pages. This is because writeback code avoids writing inodes from superblock without backing device and blockdev_superblock is such a superblock. Since it's unexpected that sync doesn't writeout dirty data for block devices be nice to users and change the behavior to do so. So now we iterate over all block devices on blockdev_super instead of iterating over all superblocks when syncing block devices. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/sync.c')
-rw-r--r--fs/sync.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/sync.c b/fs/sync.c
index 490e90201135..0b166f26362d 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -85,10 +85,14 @@ static void sync_fs_one_sb(struct super_block *sb, void *arg)
85 sb->s_op->sync_fs(sb, *(int *)arg); 85 sb->s_op->sync_fs(sb, *(int *)arg);
86} 86}
87 87
88static void sync_blkdev_one_sb(struct super_block *sb, void *arg) 88static void flush_one_bdev(struct block_device *bdev, void *arg)
89{ 89{
90 if (!(sb->s_flags & MS_RDONLY)) 90 __sync_blockdev(bdev, 0);
91 __sync_blockdev(sb->s_bdev, *(int *)arg); 91}
92
93static void sync_one_bdev(struct block_device *bdev, void *arg)
94{
95 sync_blockdev(bdev);
92} 96}
93 97
94/* 98/*
@@ -102,10 +106,10 @@ SYSCALL_DEFINE0(sync)
102 wakeup_flusher_threads(0, WB_REASON_SYNC); 106 wakeup_flusher_threads(0, WB_REASON_SYNC);
103 iterate_supers(writeback_inodes_one_sb, NULL); 107 iterate_supers(writeback_inodes_one_sb, NULL);
104 iterate_supers(sync_fs_one_sb, &nowait); 108 iterate_supers(sync_fs_one_sb, &nowait);
105 iterate_supers(sync_blkdev_one_sb, &nowait); 109 iterate_bdevs(flush_one_bdev, NULL);
106 iterate_supers(sync_inodes_one_sb, NULL); 110 iterate_supers(sync_inodes_one_sb, NULL);
107 iterate_supers(sync_fs_one_sb, &wait); 111 iterate_supers(sync_fs_one_sb, &wait);
108 iterate_supers(sync_blkdev_one_sb, &wait); 112 iterate_bdevs(sync_one_bdev, NULL);
109 if (unlikely(laptop_mode)) 113 if (unlikely(laptop_mode))
110 laptop_sync_completion(); 114 laptop_sync_completion();
111 return 0; 115 return 0;
@@ -121,10 +125,10 @@ static void do_sync_work(struct work_struct *work)
121 */ 125 */
122 iterate_supers(sync_inodes_one_sb, &nowait); 126 iterate_supers(sync_inodes_one_sb, &nowait);
123 iterate_supers(sync_fs_one_sb, &nowait); 127 iterate_supers(sync_fs_one_sb, &nowait);
124 iterate_supers(sync_blkdev_one_sb, &nowait); 128 iterate_bdevs(flush_one_bdev, NULL);
125 iterate_supers(sync_inodes_one_sb, &nowait); 129 iterate_supers(sync_inodes_one_sb, &nowait);
126 iterate_supers(sync_fs_one_sb, &nowait); 130 iterate_supers(sync_fs_one_sb, &nowait);
127 iterate_supers(sync_blkdev_one_sb, &nowait); 131 iterate_bdevs(flush_one_bdev, NULL);
128 printk("Emergency Sync complete\n"); 132 printk("Emergency Sync complete\n");
129 kfree(work); 133 kfree(work);
130} 134}