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.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 5c46ed9f3e14..fee81e8768c9 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -281,13 +281,15 @@ locked_inode_to_wb_and_lock_list(struct inode *inode)
281 wb_get(wb); 281 wb_get(wb);
282 spin_unlock(&inode->i_lock); 282 spin_unlock(&inode->i_lock);
283 spin_lock(&wb->list_lock); 283 spin_lock(&wb->list_lock);
284 wb_put(wb); /* not gonna deref it anymore */
285 284
286 /* i_wb may have changed inbetween, can't use inode_to_wb() */ 285 /* i_wb may have changed inbetween, can't use inode_to_wb() */
287 if (likely(wb == inode->i_wb)) 286 if (likely(wb == inode->i_wb)) {
288 return wb; /* @inode already has ref */ 287 wb_put(wb); /* @inode already has ref */
288 return wb;
289 }
289 290
290 spin_unlock(&wb->list_lock); 291 spin_unlock(&wb->list_lock);
292 wb_put(wb);
291 cpu_relax(); 293 cpu_relax();
292 spin_lock(&inode->i_lock); 294 spin_lock(&inode->i_lock);
293 } 295 }
@@ -1337,10 +1339,10 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
1337 * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode() 1339 * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode()
1338 * and does more profound writeback list handling in writeback_sb_inodes(). 1340 * and does more profound writeback list handling in writeback_sb_inodes().
1339 */ 1341 */
1340static int 1342static int writeback_single_inode(struct inode *inode,
1341writeback_single_inode(struct inode *inode, struct bdi_writeback *wb, 1343 struct writeback_control *wbc)
1342 struct writeback_control *wbc)
1343{ 1344{
1345 struct bdi_writeback *wb;
1344 int ret = 0; 1346 int ret = 0;
1345 1347
1346 spin_lock(&inode->i_lock); 1348 spin_lock(&inode->i_lock);
@@ -1378,7 +1380,8 @@ writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
1378 ret = __writeback_single_inode(inode, wbc); 1380 ret = __writeback_single_inode(inode, wbc);
1379 1381
1380 wbc_detach_inode(wbc); 1382 wbc_detach_inode(wbc);
1381 spin_lock(&wb->list_lock); 1383
1384 wb = inode_to_wb_and_lock_list(inode);
1382 spin_lock(&inode->i_lock); 1385 spin_lock(&inode->i_lock);
1383 /* 1386 /*
1384 * If inode is clean, remove it from writeback lists. Otherwise don't 1387 * If inode is clean, remove it from writeback lists. Otherwise don't
@@ -1453,6 +1456,7 @@ static long writeback_sb_inodes(struct super_block *sb,
1453 1456
1454 while (!list_empty(&wb->b_io)) { 1457 while (!list_empty(&wb->b_io)) {
1455 struct inode *inode = wb_inode(wb->b_io.prev); 1458 struct inode *inode = wb_inode(wb->b_io.prev);
1459 struct bdi_writeback *tmp_wb;
1456 1460
1457 if (inode->i_sb != sb) { 1461 if (inode->i_sb != sb) {
1458 if (work->sb) { 1462 if (work->sb) {
@@ -1543,15 +1547,23 @@ static long writeback_sb_inodes(struct super_block *sb,
1543 cond_resched(); 1547 cond_resched();
1544 } 1548 }
1545 1549
1546 1550 /*
1547 spin_lock(&wb->list_lock); 1551 * Requeue @inode if still dirty. Be careful as @inode may
1552 * have been switched to another wb in the meantime.
1553 */
1554 tmp_wb = inode_to_wb_and_lock_list(inode);
1548 spin_lock(&inode->i_lock); 1555 spin_lock(&inode->i_lock);
1549 if (!(inode->i_state & I_DIRTY_ALL)) 1556 if (!(inode->i_state & I_DIRTY_ALL))
1550 wrote++; 1557 wrote++;
1551 requeue_inode(inode, wb, &wbc); 1558 requeue_inode(inode, tmp_wb, &wbc);
1552 inode_sync_complete(inode); 1559 inode_sync_complete(inode);
1553 spin_unlock(&inode->i_lock); 1560 spin_unlock(&inode->i_lock);
1554 1561
1562 if (unlikely(tmp_wb != wb)) {
1563 spin_unlock(&tmp_wb->list_lock);
1564 spin_lock(&wb->list_lock);
1565 }
1566
1555 /* 1567 /*
1556 * bail out to wb_writeback() often enough to check 1568 * bail out to wb_writeback() often enough to check
1557 * background threshold and other termination conditions. 1569 * background threshold and other termination conditions.
@@ -2338,7 +2350,6 @@ EXPORT_SYMBOL(sync_inodes_sb);
2338 */ 2350 */
2339int write_inode_now(struct inode *inode, int sync) 2351int write_inode_now(struct inode *inode, int sync)
2340{ 2352{
2341 struct bdi_writeback *wb = &inode_to_bdi(inode)->wb;
2342 struct writeback_control wbc = { 2353 struct writeback_control wbc = {
2343 .nr_to_write = LONG_MAX, 2354 .nr_to_write = LONG_MAX,
2344 .sync_mode = sync ? WB_SYNC_ALL : WB_SYNC_NONE, 2355 .sync_mode = sync ? WB_SYNC_ALL : WB_SYNC_NONE,
@@ -2350,7 +2361,7 @@ int write_inode_now(struct inode *inode, int sync)
2350 wbc.nr_to_write = 0; 2361 wbc.nr_to_write = 0;
2351 2362
2352 might_sleep(); 2363 might_sleep();
2353 return writeback_single_inode(inode, wb, &wbc); 2364 return writeback_single_inode(inode, &wbc);
2354} 2365}
2355EXPORT_SYMBOL(write_inode_now); 2366EXPORT_SYMBOL(write_inode_now);
2356 2367
@@ -2367,7 +2378,7 @@ EXPORT_SYMBOL(write_inode_now);
2367 */ 2378 */
2368int sync_inode(struct inode *inode, struct writeback_control *wbc) 2379int sync_inode(struct inode *inode, struct writeback_control *wbc)
2369{ 2380{
2370 return writeback_single_inode(inode, &inode_to_bdi(inode)->wb, wbc); 2381 return writeback_single_inode(inode, wbc);
2371} 2382}
2372EXPORT_SYMBOL(sync_inode); 2383EXPORT_SYMBOL(sync_inode);
2373 2384