aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-03-12 05:59:16 -0500
committerAlex Elder <aelder@sgi.com>2010-05-19 10:58:13 -0400
commitdf308bcfec27e0c6bc83715dfd417caff5c33f19 (patch)
tree558d5b910a4de3cbb36b44eeca1e1f619f2cddf3 /fs/xfs
parentf983710758218c7aad4aae3e40a7312a21d6f55a (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.c90
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
357STATIC int 357STATIC int
358xfs_sync_fsdata( 358xfs_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
441xfs_quiesce_data( 397xfs_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
464STATIC void 427STATIC 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 */
588STATIC void 551STATIC void
589xfs_sync_worker( 552xfs_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);