diff options
author | Christoph Hellwig <hch@infradead.org> | 2010-03-12 05:59:16 -0500 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-05-19 10:58:13 -0400 |
commit | df308bcfec27e0c6bc83715dfd417caff5c33f19 (patch) | |
tree | 558d5b910a4de3cbb36b44eeca1e1f619f2cddf3 /fs/xfs | |
parent | f983710758218c7aad4aae3e40a7312a21d6f55a (diff) |
xfs: remove periodic superblock writeback
All modifications to the superblock are done transactional through
xfs_trans_log_buf, so there is no reason to initiate periodic
asynchronous writeback. This only removes the superblock from the
delwri list and will lead to sub-optimal I/O scheduling.
Cut down xfs_sync_fsdata now that it's only used for synchronous
superblock writes and move the log coverage checks into the two
callers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 90 |
1 files changed, 27 insertions, 63 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index a7ba355c21b6..728db015f39c 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -356,68 +356,24 @@ xfs_commit_dummy_trans( | |||
356 | 356 | ||
357 | STATIC int | 357 | STATIC int |
358 | xfs_sync_fsdata( | 358 | xfs_sync_fsdata( |
359 | struct xfs_mount *mp, | 359 | struct xfs_mount *mp) |
360 | int flags) | ||
361 | { | 360 | { |
362 | struct xfs_buf *bp; | 361 | struct xfs_buf *bp; |
363 | struct xfs_buf_log_item *bip; | ||
364 | int error = 0; | ||
365 | 362 | ||
366 | /* | 363 | /* |
367 | * If this is xfssyncd() then only sync the superblock if we can | 364 | * If the buffer is pinned then push on the log so we won't get stuck |
368 | * lock it without sleeping and it is not pinned. | 365 | * waiting in the write for someone, maybe ourselves, to flush the log. |
366 | * | ||
367 | * Even though we just pushed the log above, we did not have the | ||
368 | * superblock buffer locked at that point so it can become pinned in | ||
369 | * between there and here. | ||
369 | */ | 370 | */ |
370 | if (flags & SYNC_TRYLOCK) { | 371 | bp = xfs_getsb(mp, 0); |
371 | ASSERT(!(flags & SYNC_WAIT)); | 372 | if (XFS_BUF_ISPINNED(bp)) |
372 | 373 | xfs_log_force(mp, 0); | |
373 | bp = xfs_getsb(mp, XBF_TRYLOCK); | ||
374 | if (!bp) | ||
375 | goto out; | ||
376 | |||
377 | bip = XFS_BUF_FSPRIVATE(bp, struct xfs_buf_log_item *); | ||
378 | if (!bip || !xfs_buf_item_dirty(bip) || XFS_BUF_ISPINNED(bp)) | ||
379 | goto out_brelse; | ||
380 | } else { | ||
381 | bp = xfs_getsb(mp, 0); | ||
382 | |||
383 | /* | ||
384 | * If the buffer is pinned then push on the log so we won't | ||
385 | * get stuck waiting in the write for someone, maybe | ||
386 | * ourselves, to flush the log. | ||
387 | * | ||
388 | * Even though we just pushed the log above, we did not have | ||
389 | * the superblock buffer locked at that point so it can | ||
390 | * become pinned in between there and here. | ||
391 | */ | ||
392 | if (XFS_BUF_ISPINNED(bp)) | ||
393 | xfs_log_force(mp, 0); | ||
394 | } | ||
395 | |||
396 | |||
397 | if (flags & SYNC_WAIT) | ||
398 | XFS_BUF_UNASYNC(bp); | ||
399 | else | ||
400 | XFS_BUF_ASYNC(bp); | ||
401 | |||
402 | error = xfs_bwrite(mp, bp); | ||
403 | if (error) | ||
404 | return error; | ||
405 | |||
406 | /* | ||
407 | * If this is a data integrity sync make sure all pending buffers | ||
408 | * are flushed out for the log coverage check below. | ||
409 | */ | ||
410 | if (flags & SYNC_WAIT) | ||
411 | xfs_flush_buftarg(mp->m_ddev_targp, 1); | ||
412 | |||
413 | if (xfs_log_need_covered(mp)) | ||
414 | error = xfs_commit_dummy_trans(mp, flags); | ||
415 | return error; | ||
416 | 374 | ||
417 | out_brelse: | 375 | XFS_BUF_UNASYNC(bp); |
418 | xfs_buf_relse(bp); | 376 | return xfs_bwrite(mp, bp); |
419 | out: | ||
420 | return error; | ||
421 | } | 377 | } |
422 | 378 | ||
423 | /* | 379 | /* |
@@ -441,7 +397,7 @@ int | |||
441 | xfs_quiesce_data( | 397 | xfs_quiesce_data( |
442 | struct xfs_mount *mp) | 398 | struct xfs_mount *mp) |
443 | { | 399 | { |
444 | int error; | 400 | int error, error2 = 0; |
445 | 401 | ||
446 | /* push non-blocking */ | 402 | /* push non-blocking */ |
447 | xfs_sync_data(mp, 0); | 403 | xfs_sync_data(mp, 0); |
@@ -452,13 +408,20 @@ xfs_quiesce_data( | |||
452 | xfs_qm_sync(mp, SYNC_WAIT); | 408 | xfs_qm_sync(mp, SYNC_WAIT); |
453 | 409 | ||
454 | /* write superblock and hoover up shutdown errors */ | 410 | /* write superblock and hoover up shutdown errors */ |
455 | error = xfs_sync_fsdata(mp, SYNC_WAIT); | 411 | error = xfs_sync_fsdata(mp); |
412 | |||
413 | /* make sure all delwri buffers are written out */ | ||
414 | xfs_flush_buftarg(mp->m_ddev_targp, 1); | ||
415 | |||
416 | /* mark the log as covered if needed */ | ||
417 | if (xfs_log_need_covered(mp)) | ||
418 | error2 = xfs_commit_dummy_trans(mp, SYNC_WAIT); | ||
456 | 419 | ||
457 | /* flush data-only devices */ | 420 | /* flush data-only devices */ |
458 | if (mp->m_rtdev_targp) | 421 | if (mp->m_rtdev_targp) |
459 | XFS_bflush(mp->m_rtdev_targp); | 422 | XFS_bflush(mp->m_rtdev_targp); |
460 | 423 | ||
461 | return error; | 424 | return error ? error : error2; |
462 | } | 425 | } |
463 | 426 | ||
464 | STATIC void | 427 | STATIC void |
@@ -581,9 +544,9 @@ xfs_flush_inodes( | |||
581 | } | 544 | } |
582 | 545 | ||
583 | /* | 546 | /* |
584 | * Every sync period we need to unpin all items, reclaim inodes, sync | 547 | * Every sync period we need to unpin all items, reclaim inodes and sync |
585 | * quota and write out the superblock. We might need to cover the log | 548 | * disk quotas. We might need to cover the log to indicate that the |
586 | * to indicate it is idle. | 549 | * filesystem is idle. |
587 | */ | 550 | */ |
588 | STATIC void | 551 | STATIC void |
589 | xfs_sync_worker( | 552 | xfs_sync_worker( |
@@ -597,7 +560,8 @@ xfs_sync_worker( | |||
597 | xfs_reclaim_inodes(mp, 0); | 560 | xfs_reclaim_inodes(mp, 0); |
598 | /* dgc: errors ignored here */ | 561 | /* dgc: errors ignored here */ |
599 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); | 562 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); |
600 | error = xfs_sync_fsdata(mp, SYNC_TRYLOCK); | 563 | if (xfs_log_need_covered(mp)) |
564 | error = xfs_commit_dummy_trans(mp, 0); | ||
601 | } | 565 | } |
602 | mp->m_sync_seq++; | 566 | mp->m_sync_seq++; |
603 | wake_up(&mp->m_wait_single_sync_task); | 567 | wake_up(&mp->m_wait_single_sync_task); |