diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2010-06-01 05:08:43 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-06-01 05:08:43 -0400 |
commit | 0e3c9a2284f5417f196e327c254d0b84c9ee8929 (patch) | |
tree | e3fb40ebe7d042b4b3c1042bc7f2edaf7fb6eee0 | |
parent | f17625b318d9b151e7bd41e31223e9d89b2aaa77 (diff) |
Revert "writeback: fix WB_SYNC_NONE writeback from umount"
This reverts commit e913fc825dc685a444cb4c1d0f9d32f372f59861.
We are investigating a hang associated with the WB_SYNC_NONE changes,
so revert them for now.
Conflicts:
fs/fs-writeback.c
mm/page-writeback.c
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r-- | fs/fs-writeback.c | 48 | ||||
-rw-r--r-- | fs/sync.c | 2 | ||||
-rw-r--r-- | include/linux/backing-dev.h | 2 | ||||
-rw-r--r-- | include/linux/writeback.h | 10 | ||||
-rw-r--r-- | mm/page-writeback.c | 4 |
5 files changed, 15 insertions, 51 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 6753912641b4..408a7877b79d 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -45,7 +45,6 @@ struct wb_writeback_args { | |||
45 | unsigned int for_kupdate:1; | 45 | unsigned int for_kupdate:1; |
46 | unsigned int range_cyclic:1; | 46 | unsigned int range_cyclic:1; |
47 | unsigned int for_background:1; | 47 | unsigned int for_background:1; |
48 | unsigned int sb_pinned:1; | ||
49 | }; | 48 | }; |
50 | 49 | ||
51 | /* | 50 | /* |
@@ -231,11 +230,6 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi, | |||
231 | .sync_mode = WB_SYNC_ALL, | 230 | .sync_mode = WB_SYNC_ALL, |
232 | .nr_pages = LONG_MAX, | 231 | .nr_pages = LONG_MAX, |
233 | .range_cyclic = 0, | 232 | .range_cyclic = 0, |
234 | /* | ||
235 | * Setting sb_pinned is not necessary for WB_SYNC_ALL, but | ||
236 | * lets make it explicitly clear. | ||
237 | */ | ||
238 | .sb_pinned = 1, | ||
239 | }; | 233 | }; |
240 | struct bdi_work work; | 234 | struct bdi_work work; |
241 | 235 | ||
@@ -251,23 +245,21 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi, | |||
251 | * @bdi: the backing device to write from | 245 | * @bdi: the backing device to write from |
252 | * @sb: write inodes from this super_block | 246 | * @sb: write inodes from this super_block |
253 | * @nr_pages: the number of pages to write | 247 | * @nr_pages: the number of pages to write |
254 | * @sb_locked: caller already holds sb umount sem. | ||
255 | * | 248 | * |
256 | * Description: | 249 | * Description: |
257 | * This does WB_SYNC_NONE opportunistic writeback. The IO is only | 250 | * This does WB_SYNC_NONE opportunistic writeback. The IO is only |
258 | * started when this function returns, we make no guarentees on | 251 | * started when this function returns, we make no guarentees on |
259 | * completion. Caller specifies whether sb umount sem is held already or not. | 252 | * completion. Caller need not hold sb s_umount semaphore. |
260 | * | 253 | * |
261 | */ | 254 | */ |
262 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, | 255 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, |
263 | long nr_pages, int sb_locked) | 256 | long nr_pages) |
264 | { | 257 | { |
265 | struct wb_writeback_args args = { | 258 | struct wb_writeback_args args = { |
266 | .sb = sb, | 259 | .sb = sb, |
267 | .sync_mode = WB_SYNC_NONE, | 260 | .sync_mode = WB_SYNC_NONE, |
268 | .nr_pages = nr_pages, | 261 | .nr_pages = nr_pages, |
269 | .range_cyclic = 1, | 262 | .range_cyclic = 1, |
270 | .sb_pinned = sb_locked, | ||
271 | }; | 263 | }; |
272 | 264 | ||
273 | /* | 265 | /* |
@@ -592,7 +584,7 @@ static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc, | |||
592 | /* | 584 | /* |
593 | * Caller must already hold the ref for this | 585 | * Caller must already hold the ref for this |
594 | */ | 586 | */ |
595 | if (wbc->sync_mode == WB_SYNC_ALL || wbc->sb_pinned) { | 587 | if (wbc->sync_mode == WB_SYNC_ALL) { |
596 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); | 588 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); |
597 | return SB_NOT_PINNED; | 589 | return SB_NOT_PINNED; |
598 | } | 590 | } |
@@ -766,7 +758,6 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
766 | .for_kupdate = args->for_kupdate, | 758 | .for_kupdate = args->for_kupdate, |
767 | .for_background = args->for_background, | 759 | .for_background = args->for_background, |
768 | .range_cyclic = args->range_cyclic, | 760 | .range_cyclic = args->range_cyclic, |
769 | .sb_pinned = args->sb_pinned, | ||
770 | }; | 761 | }; |
771 | unsigned long oldest_jif; | 762 | unsigned long oldest_jif; |
772 | long wrote = 0; | 763 | long wrote = 0; |
@@ -1214,18 +1205,6 @@ static void wait_sb_inodes(struct super_block *sb) | |||
1214 | iput(old_inode); | 1205 | iput(old_inode); |
1215 | } | 1206 | } |
1216 | 1207 | ||
1217 | static void __writeback_inodes_sb(struct super_block *sb, int sb_locked) | ||
1218 | { | ||
1219 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); | ||
1220 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); | ||
1221 | long nr_to_write; | ||
1222 | |||
1223 | nr_to_write = nr_dirty + nr_unstable + | ||
1224 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); | ||
1225 | |||
1226 | bdi_start_writeback(sb->s_bdi, sb, nr_to_write, sb_locked); | ||
1227 | } | ||
1228 | |||
1229 | /** | 1208 | /** |
1230 | * writeback_inodes_sb - writeback dirty inodes from given super_block | 1209 | * writeback_inodes_sb - writeback dirty inodes from given super_block |
1231 | * @sb: the superblock | 1210 | * @sb: the superblock |
@@ -1237,21 +1216,16 @@ static void __writeback_inodes_sb(struct super_block *sb, int sb_locked) | |||
1237 | */ | 1216 | */ |
1238 | void writeback_inodes_sb(struct super_block *sb) | 1217 | void writeback_inodes_sb(struct super_block *sb) |
1239 | { | 1218 | { |
1240 | __writeback_inodes_sb(sb, 0); | 1219 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); |
1241 | } | 1220 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); |
1242 | EXPORT_SYMBOL(writeback_inodes_sb); | 1221 | long nr_to_write; |
1243 | 1222 | ||
1244 | /** | 1223 | nr_to_write = nr_dirty + nr_unstable + |
1245 | * writeback_inodes_sb_locked - writeback dirty inodes from given super_block | 1224 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); |
1246 | * @sb: the superblock | 1225 | |
1247 | * | 1226 | bdi_start_writeback(sb->s_bdi, sb, nr_to_write); |
1248 | * Like writeback_inodes_sb(), except the caller already holds the | ||
1249 | * sb umount sem. | ||
1250 | */ | ||
1251 | void writeback_inodes_sb_locked(struct super_block *sb) | ||
1252 | { | ||
1253 | __writeback_inodes_sb(sb, 1); | ||
1254 | } | 1227 | } |
1228 | EXPORT_SYMBOL(writeback_inodes_sb); | ||
1255 | 1229 | ||
1256 | /** | 1230 | /** |
1257 | * writeback_inodes_sb_if_idle - start writeback if none underway | 1231 | * writeback_inodes_sb_if_idle - start writeback if none underway |
@@ -42,7 +42,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) | |||
42 | if (wait) | 42 | if (wait) |
43 | sync_inodes_sb(sb); | 43 | sync_inodes_sb(sb); |
44 | else | 44 | else |
45 | writeback_inodes_sb_locked(sb); | 45 | writeback_inodes_sb(sb); |
46 | 46 | ||
47 | if (sb->s_op->sync_fs) | 47 | if (sb->s_op->sync_fs) |
48 | sb->s_op->sync_fs(sb, wait); | 48 | sb->s_op->sync_fs(sb, wait); |
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index e6e0cb5437e6..aee5f6ce166e 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h | |||
@@ -106,7 +106,7 @@ int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); | |||
106 | void bdi_unregister(struct backing_dev_info *bdi); | 106 | void bdi_unregister(struct backing_dev_info *bdi); |
107 | int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); | 107 | int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); |
108 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, | 108 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, |
109 | long nr_pages, int sb_locked); | 109 | long nr_pages); |
110 | int bdi_writeback_task(struct bdi_writeback *wb); | 110 | int bdi_writeback_task(struct bdi_writeback *wb); |
111 | int bdi_has_dirty_io(struct backing_dev_info *bdi); | 111 | int bdi_has_dirty_io(struct backing_dev_info *bdi); |
112 | void bdi_arm_supers_timer(void); | 112 | void bdi_arm_supers_timer(void); |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index cc97d6caf2b3..f64134653a8c 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -65,15 +65,6 @@ struct writeback_control { | |||
65 | * so we use a single control to update them | 65 | * so we use a single control to update them |
66 | */ | 66 | */ |
67 | unsigned no_nrwrite_index_update:1; | 67 | unsigned no_nrwrite_index_update:1; |
68 | |||
69 | /* | ||
70 | * For WB_SYNC_ALL, the sb must always be pinned. For WB_SYNC_NONE, | ||
71 | * the writeback code will pin the sb for the caller. However, | ||
72 | * for eg umount, the caller does WB_SYNC_NONE but already has | ||
73 | * the sb pinned. If the below is set, caller already has the | ||
74 | * sb pinned. | ||
75 | */ | ||
76 | unsigned sb_pinned:1; | ||
77 | }; | 68 | }; |
78 | 69 | ||
79 | /* | 70 | /* |
@@ -82,7 +73,6 @@ struct writeback_control { | |||
82 | struct bdi_writeback; | 73 | struct bdi_writeback; |
83 | int inode_wait(void *); | 74 | int inode_wait(void *); |
84 | void writeback_inodes_sb(struct super_block *); | 75 | void writeback_inodes_sb(struct super_block *); |
85 | void writeback_inodes_sb_locked(struct super_block *); | ||
86 | int writeback_inodes_sb_if_idle(struct super_block *); | 76 | int writeback_inodes_sb_if_idle(struct super_block *); |
87 | void sync_inodes_sb(struct super_block *); | 77 | void sync_inodes_sb(struct super_block *); |
88 | void writeback_inodes_wbc(struct writeback_control *wbc); | 78 | void writeback_inodes_wbc(struct writeback_control *wbc); |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index b289310e2c89..5fa63bdf52e4 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -597,7 +597,7 @@ static void balance_dirty_pages(struct address_space *mapping, | |||
597 | (!laptop_mode && ((global_page_state(NR_FILE_DIRTY) | 597 | (!laptop_mode && ((global_page_state(NR_FILE_DIRTY) |
598 | + global_page_state(NR_UNSTABLE_NFS)) | 598 | + global_page_state(NR_UNSTABLE_NFS)) |
599 | > background_thresh))) | 599 | > background_thresh))) |
600 | bdi_start_writeback(bdi, NULL, 0, 0); | 600 | bdi_start_writeback(bdi, NULL, 0); |
601 | } | 601 | } |
602 | 602 | ||
603 | void set_page_dirty_balance(struct page *page, int page_mkwrite) | 603 | void set_page_dirty_balance(struct page *page, int page_mkwrite) |
@@ -707,7 +707,7 @@ void laptop_mode_timer_fn(unsigned long data) | |||
707 | */ | 707 | */ |
708 | 708 | ||
709 | if (bdi_has_dirty_io(&q->backing_dev_info)) | 709 | if (bdi_has_dirty_io(&q->backing_dev_info)) |
710 | bdi_start_writeback(&q->backing_dev_info, NULL, nr_pages, 0); | 710 | bdi_start_writeback(&q->backing_dev_info, NULL, nr_pages); |
711 | } | 711 | } |
712 | 712 | ||
713 | /* | 713 | /* |