mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
writeback: Fix periodic writeback after fs mount
commit a5faeaf910
upstream.
Code in blkdev.c moves a device inode to default_backing_dev_info when
the last reference to the device is put and moves the device inode back
to its bdi when the first reference is acquired. This includes moving to
wb.b_dirty list if the device inode is dirty. The code however doesn't
setup timer to wake corresponding flusher thread and while wb.b_dirty
list is non-empty __mark_inode_dirty() will not set it up either. Thus
periodic writeback is effectively disabled until a sync(2) call which can
lead to unexpected data loss in case of crash or power failure.
Fix the problem by setting up a timer for periodic writeback in case we
add the first dirty inode to wb.b_dirty list in bdev_inode_switch_bdi().
Reported-by: Bert De Jonghe <Bert.DeJonghe@amplidata.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
81a4648386
commit
9fa65e0973
1 changed files with 8 additions and 1 deletions
|
@ -58,17 +58,24 @@ static void bdev_inode_switch_bdi(struct inode *inode,
|
|||
struct backing_dev_info *dst)
|
||||
{
|
||||
struct backing_dev_info *old = inode->i_data.backing_dev_info;
|
||||
bool wakeup_bdi = false;
|
||||
|
||||
if (unlikely(dst == old)) /* deadlock avoidance */
|
||||
return;
|
||||
bdi_lock_two(&old->wb, &dst->wb);
|
||||
spin_lock(&inode->i_lock);
|
||||
inode->i_data.backing_dev_info = dst;
|
||||
if (inode->i_state & I_DIRTY)
|
||||
if (inode->i_state & I_DIRTY) {
|
||||
if (bdi_cap_writeback_dirty(dst) && !wb_has_dirty_io(&dst->wb))
|
||||
wakeup_bdi = true;
|
||||
list_move(&inode->i_wb_list, &dst->wb.b_dirty);
|
||||
}
|
||||
spin_unlock(&inode->i_lock);
|
||||
spin_unlock(&old->wb.list_lock);
|
||||
spin_unlock(&dst->wb.list_lock);
|
||||
|
||||
if (wakeup_bdi)
|
||||
bdi_wakeup_thread_delayed(dst);
|
||||
}
|
||||
|
||||
/* Kill _all_ buffers and pagecache , dirty or not.. */
|
||||
|
|
Loading…
Reference in a new issue