aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_cil.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r--fs/xfs/xfs_log_cil.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 53abd6b0a33..9b21f80f31c 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -336,6 +336,7 @@ xfs_log_commit_cil(
336{ 336{
337 struct log *log = mp->m_log; 337 struct log *log = mp->m_log;
338 int log_flags = 0; 338 int log_flags = 0;
339 int push = 0;
339 340
340 if (flags & XFS_TRANS_RELEASE_LOG_RES) 341 if (flags & XFS_TRANS_RELEASE_LOG_RES)
341 log_flags = XFS_LOG_REL_PERM_RESERV; 342 log_flags = XFS_LOG_REL_PERM_RESERV;
@@ -365,8 +366,20 @@ xfs_log_commit_cil(
365 xfs_log_done(mp, tp->t_ticket, NULL, log_flags); 366 xfs_log_done(mp, tp->t_ticket, NULL, log_flags);
366 xfs_trans_unreserve_and_mod_sb(tp); 367 xfs_trans_unreserve_and_mod_sb(tp);
367 368
368 /* background commit is allowed again */ 369 /* check for background commit before unlock */
370 if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log))
371 push = 1;
369 up_read(&log->l_cilp->xc_ctx_lock); 372 up_read(&log->l_cilp->xc_ctx_lock);
373
374 /*
375 * We need to push CIL every so often so we don't cache more than we
376 * can fit in the log. The limit really is that a checkpoint can't be
377 * more than half the log (the current checkpoint is not allowed to
378 * overwrite the previous checkpoint), but commit latency and memory
379 * usage limit this to a smaller size in most cases.
380 */
381 if (push)
382 xlog_cil_push(log, 0);
370 return 0; 383 return 0;
371} 384}
372 385
@@ -429,18 +442,25 @@ xlog_cil_push(
429 if (!cil) 442 if (!cil)
430 return 0; 443 return 0;
431 444
432 /* XXX: don't sleep for background? */
433 new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); 445 new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS);
434 new_ctx->ticket = xlog_cil_ticket_alloc(log); 446 new_ctx->ticket = xlog_cil_ticket_alloc(log);
435 447
436 /* lock out transaction commit */ 448 /* lock out transaction commit, but don't block on background push */
437 down_write(&cil->xc_ctx_lock); 449 if (!down_write_trylock(&cil->xc_ctx_lock)) {
450 if (!push_now)
451 goto out_free_ticket;
452 down_write(&cil->xc_ctx_lock);
453 }
438 ctx = cil->xc_ctx; 454 ctx = cil->xc_ctx;
439 455
440 /* check if we've anything to push */ 456 /* check if we've anything to push */
441 if (list_empty(&cil->xc_cil)) 457 if (list_empty(&cil->xc_cil))
442 goto out_skip; 458 goto out_skip;
443 459
460 /* check for spurious background flush */
461 if (!push_now && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log))
462 goto out_skip;
463
444 /* 464 /*
445 * pull all the log vectors off the items in the CIL, and 465 * pull all the log vectors off the items in the CIL, and
446 * remove the items from the CIL. We don't need the CIL lock 466 * remove the items from the CIL. We don't need the CIL lock
@@ -584,6 +604,7 @@ restart:
584 604
585out_skip: 605out_skip:
586 up_write(&cil->xc_ctx_lock); 606 up_write(&cil->xc_ctx_lock);
607out_free_ticket:
587 xfs_log_ticket_put(new_ctx->ticket); 608 xfs_log_ticket_put(new_ctx->ticket);
588 kmem_free(new_ctx); 609 kmem_free(new_ctx);
589 return 0; 610 return 0;