aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 4b37f7cea4dd..1d1088f48bc2 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -42,9 +42,9 @@ struct wb_writeback_args {
42 long nr_pages; 42 long nr_pages;
43 struct super_block *sb; 43 struct super_block *sb;
44 enum writeback_sync_modes sync_mode; 44 enum writeback_sync_modes sync_mode;
45 int for_kupdate:1; 45 unsigned int for_kupdate:1;
46 int range_cyclic:1; 46 unsigned int range_cyclic:1;
47 int for_background:1; 47 unsigned int for_background:1;
48}; 48};
49 49
50/* 50/*
@@ -398,11 +398,11 @@ static void inode_wait_for_writeback(struct inode *inode)
398 wait_queue_head_t *wqh; 398 wait_queue_head_t *wqh;
399 399
400 wqh = bit_waitqueue(&inode->i_state, __I_SYNC); 400 wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
401 do { 401 while (inode->i_state & I_SYNC) {
402 spin_unlock(&inode_lock); 402 spin_unlock(&inode_lock);
403 __wait_on_bit(wqh, &wq, inode_wait, TASK_UNINTERRUPTIBLE); 403 __wait_on_bit(wqh, &wq, inode_wait, TASK_UNINTERRUPTIBLE);
404 spin_lock(&inode_lock); 404 spin_lock(&inode_lock);
405 } while (inode->i_state & I_SYNC); 405 }
406} 406}
407 407
408/* 408/*
@@ -452,11 +452,9 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
452 452
453 BUG_ON(inode->i_state & I_SYNC); 453 BUG_ON(inode->i_state & I_SYNC);
454 454
455 /* Set I_SYNC, reset I_DIRTY */ 455 /* Set I_SYNC, reset I_DIRTY_PAGES */
456 dirty = inode->i_state & I_DIRTY;
457 inode->i_state |= I_SYNC; 456 inode->i_state |= I_SYNC;
458 inode->i_state &= ~I_DIRTY; 457 inode->i_state &= ~I_DIRTY_PAGES;
459
460 spin_unlock(&inode_lock); 458 spin_unlock(&inode_lock);
461 459
462 ret = do_writepages(mapping, wbc); 460 ret = do_writepages(mapping, wbc);
@@ -472,6 +470,15 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
472 ret = err; 470 ret = err;
473 } 471 }
474 472
473 /*
474 * Some filesystems may redirty the inode during the writeback
475 * due to delalloc, clear dirty metadata flags right before
476 * write_inode()
477 */
478 spin_lock(&inode_lock);
479 dirty = inode->i_state & I_DIRTY;
480 inode->i_state &= ~(I_DIRTY_SYNC | I_DIRTY_DATASYNC);
481 spin_unlock(&inode_lock);
475 /* Don't write the inode if only I_DIRTY_PAGES was set */ 482 /* Don't write the inode if only I_DIRTY_PAGES was set */
476 if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { 483 if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
477 int err = write_inode(inode, wbc); 484 int err = write_inode(inode, wbc);
@@ -852,6 +859,12 @@ static long wb_check_old_data_flush(struct bdi_writeback *wb)
852 unsigned long expired; 859 unsigned long expired;
853 long nr_pages; 860 long nr_pages;
854 861
862 /*
863 * When set to zero, disable periodic writeback
864 */
865 if (!dirty_writeback_interval)
866 return 0;
867
855 expired = wb->last_old_flush + 868 expired = wb->last_old_flush +
856 msecs_to_jiffies(dirty_writeback_interval * 10); 869 msecs_to_jiffies(dirty_writeback_interval * 10);
857 if (time_before(jiffies, expired)) 870 if (time_before(jiffies, expired))
@@ -947,8 +960,17 @@ int bdi_writeback_task(struct bdi_writeback *wb)
947 break; 960 break;
948 } 961 }
949 962
950 wait_jiffies = msecs_to_jiffies(dirty_writeback_interval * 10); 963 if (dirty_writeback_interval) {
951 schedule_timeout_interruptible(wait_jiffies); 964 wait_jiffies = msecs_to_jiffies(dirty_writeback_interval * 10);
965 schedule_timeout_interruptible(wait_jiffies);
966 } else {
967 set_current_state(TASK_INTERRUPTIBLE);
968 if (list_empty_careful(&wb->bdi->work_list) &&
969 !kthread_should_stop())
970 schedule();
971 __set_current_state(TASK_RUNNING);
972 }
973
952 try_to_freeze(); 974 try_to_freeze();
953 } 975 }
954 976