diff options
Diffstat (limited to 'fs/fs-writeback.c')
| -rw-r--r-- | fs/fs-writeback.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 0f629571234f..76f546d56a64 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -193,7 +193,8 @@ static void bdi_wait_on_work_clear(struct bdi_work *work) | |||
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static void bdi_alloc_queue_work(struct backing_dev_info *bdi, | 195 | static void bdi_alloc_queue_work(struct backing_dev_info *bdi, |
| 196 | struct wb_writeback_args *args) | 196 | struct wb_writeback_args *args, |
| 197 | int wait) | ||
| 197 | { | 198 | { |
| 198 | struct bdi_work *work; | 199 | struct bdi_work *work; |
| 199 | 200 | ||
| @@ -205,6 +206,8 @@ static void bdi_alloc_queue_work(struct backing_dev_info *bdi, | |||
| 205 | if (work) { | 206 | if (work) { |
| 206 | bdi_work_init(work, args); | 207 | bdi_work_init(work, args); |
| 207 | bdi_queue_work(bdi, work); | 208 | bdi_queue_work(bdi, work); |
| 209 | if (wait) | ||
| 210 | bdi_wait_on_work_clear(work); | ||
| 208 | } else { | 211 | } else { |
| 209 | struct bdi_writeback *wb = &bdi->wb; | 212 | struct bdi_writeback *wb = &bdi->wb; |
| 210 | 213 | ||
| @@ -279,7 +282,7 @@ void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, | |||
| 279 | args.for_background = 1; | 282 | args.for_background = 1; |
| 280 | } | 283 | } |
| 281 | 284 | ||
| 282 | bdi_alloc_queue_work(bdi, &args); | 285 | bdi_alloc_queue_work(bdi, &args, sb_locked); |
| 283 | } | 286 | } |
| 284 | 287 | ||
| 285 | /* | 288 | /* |
| @@ -909,6 +912,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
| 909 | 912 | ||
| 910 | while ((work = get_next_work_item(bdi, wb)) != NULL) { | 913 | while ((work = get_next_work_item(bdi, wb)) != NULL) { |
| 911 | struct wb_writeback_args args = work->args; | 914 | struct wb_writeback_args args = work->args; |
| 915 | int post_clear; | ||
| 912 | 916 | ||
| 913 | /* | 917 | /* |
| 914 | * Override sync mode, in case we must wait for completion | 918 | * Override sync mode, in case we must wait for completion |
| @@ -916,11 +920,13 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
| 916 | if (force_wait) | 920 | if (force_wait) |
| 917 | work->args.sync_mode = args.sync_mode = WB_SYNC_ALL; | 921 | work->args.sync_mode = args.sync_mode = WB_SYNC_ALL; |
| 918 | 922 | ||
| 923 | post_clear = WB_SYNC_ALL || args.sb_pinned; | ||
| 924 | |||
| 919 | /* | 925 | /* |
| 920 | * If this isn't a data integrity operation, just notify | 926 | * If this isn't a data integrity operation, just notify |
| 921 | * that we have seen this work and we are now starting it. | 927 | * that we have seen this work and we are now starting it. |
| 922 | */ | 928 | */ |
| 923 | if (args.sync_mode == WB_SYNC_NONE) | 929 | if (!post_clear) |
| 924 | wb_clear_pending(wb, work); | 930 | wb_clear_pending(wb, work); |
| 925 | 931 | ||
| 926 | wrote += wb_writeback(wb, &args); | 932 | wrote += wb_writeback(wb, &args); |
| @@ -929,7 +935,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
| 929 | * This is a data integrity writeback, so only do the | 935 | * This is a data integrity writeback, so only do the |
| 930 | * notification when we have completed the work. | 936 | * notification when we have completed the work. |
| 931 | */ | 937 | */ |
| 932 | if (args.sync_mode == WB_SYNC_ALL) | 938 | if (post_clear) |
| 933 | wb_clear_pending(wb, work); | 939 | wb_clear_pending(wb, work); |
| 934 | } | 940 | } |
| 935 | 941 | ||
| @@ -1000,7 +1006,7 @@ static void bdi_writeback_all(struct super_block *sb, long nr_pages) | |||
| 1000 | if (!bdi_has_dirty_io(bdi)) | 1006 | if (!bdi_has_dirty_io(bdi)) |
| 1001 | continue; | 1007 | continue; |
| 1002 | 1008 | ||
| 1003 | bdi_alloc_queue_work(bdi, &args); | 1009 | bdi_alloc_queue_work(bdi, &args, 0); |
| 1004 | } | 1010 | } |
| 1005 | 1011 | ||
| 1006 | rcu_read_unlock(); | 1012 | rcu_read_unlock(); |
