diff options
author | Dave Chinner <david@fromorbit.com> | 2014-03-13 04:12:13 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-03-13 04:12:13 -0400 |
commit | 730357a5cb72d9754a396a350653ff98a9e44783 (patch) | |
tree | 8d97cc0f756e803c8c2f991cab8f1ba00d6dbbe4 /fs/xfs/xfs_log_cil.c | |
parent | b6db0551fddfc8826bc07fc99d64d830530b2d77 (diff) | |
parent | 93a8614e3a4dccd526aca34e892ac0b27f64b506 (diff) |
Merge branch 'xfs-stack-fixes' into for-next
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r-- | fs/xfs/xfs_log_cil.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index b57a8e08b3d1..7e5455391176 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -499,13 +499,6 @@ xlog_cil_push( | |||
499 | cil->xc_ctx = new_ctx; | 499 | cil->xc_ctx = new_ctx; |
500 | 500 | ||
501 | /* | 501 | /* |
502 | * mirror the new sequence into the cil structure so that we can do | ||
503 | * unlocked checks against the current sequence in log forces without | ||
504 | * risking deferencing a freed context pointer. | ||
505 | */ | ||
506 | cil->xc_current_sequence = new_ctx->sequence; | ||
507 | |||
508 | /* | ||
509 | * The switch is now done, so we can drop the context lock and move out | 502 | * The switch is now done, so we can drop the context lock and move out |
510 | * of a shared context. We can't just go straight to the commit record, | 503 | * of a shared context. We can't just go straight to the commit record, |
511 | * though - we need to synchronise with previous and future commits so | 504 | * though - we need to synchronise with previous and future commits so |
@@ -523,8 +516,15 @@ xlog_cil_push( | |||
523 | * Hence we need to add this context to the committing context list so | 516 | * Hence we need to add this context to the committing context list so |
524 | * that higher sequences will wait for us to write out a commit record | 517 | * that higher sequences will wait for us to write out a commit record |
525 | * before they do. | 518 | * before they do. |
519 | * | ||
520 | * xfs_log_force_lsn requires us to mirror the new sequence into the cil | ||
521 | * structure atomically with the addition of this sequence to the | ||
522 | * committing list. This also ensures that we can do unlocked checks | ||
523 | * against the current sequence in log forces without risking | ||
524 | * deferencing a freed context pointer. | ||
526 | */ | 525 | */ |
527 | spin_lock(&cil->xc_push_lock); | 526 | spin_lock(&cil->xc_push_lock); |
527 | cil->xc_current_sequence = new_ctx->sequence; | ||
528 | list_add(&ctx->committing, &cil->xc_committing); | 528 | list_add(&ctx->committing, &cil->xc_committing); |
529 | spin_unlock(&cil->xc_push_lock); | 529 | spin_unlock(&cil->xc_push_lock); |
530 | up_write(&cil->xc_ctx_lock); | 530 | up_write(&cil->xc_ctx_lock); |
@@ -662,8 +662,14 @@ xlog_cil_push_background( | |||
662 | 662 | ||
663 | } | 663 | } |
664 | 664 | ||
665 | /* | ||
666 | * xlog_cil_push_now() is used to trigger an immediate CIL push to the sequence | ||
667 | * number that is passed. When it returns, the work will be queued for | ||
668 | * @push_seq, but it won't be completed. The caller is expected to do any | ||
669 | * waiting for push_seq to complete if it is required. | ||
670 | */ | ||
665 | static void | 671 | static void |
666 | xlog_cil_push_foreground( | 672 | xlog_cil_push_now( |
667 | struct xlog *log, | 673 | struct xlog *log, |
668 | xfs_lsn_t push_seq) | 674 | xfs_lsn_t push_seq) |
669 | { | 675 | { |
@@ -688,10 +694,8 @@ xlog_cil_push_foreground( | |||
688 | } | 694 | } |
689 | 695 | ||
690 | cil->xc_push_seq = push_seq; | 696 | cil->xc_push_seq = push_seq; |
697 | queue_work(log->l_mp->m_cil_workqueue, &cil->xc_push_work); | ||
691 | spin_unlock(&cil->xc_push_lock); | 698 | spin_unlock(&cil->xc_push_lock); |
692 | |||
693 | /* do the push now */ | ||
694 | xlog_cil_push(log); | ||
695 | } | 699 | } |
696 | 700 | ||
697 | bool | 701 | bool |
@@ -795,7 +799,8 @@ xlog_cil_force_lsn( | |||
795 | * xlog_cil_push() handles racing pushes for the same sequence, | 799 | * xlog_cil_push() handles racing pushes for the same sequence, |
796 | * so no need to deal with it here. | 800 | * so no need to deal with it here. |
797 | */ | 801 | */ |
798 | xlog_cil_push_foreground(log, sequence); | 802 | restart: |
803 | xlog_cil_push_now(log, sequence); | ||
799 | 804 | ||
800 | /* | 805 | /* |
801 | * See if we can find a previous sequence still committing. | 806 | * See if we can find a previous sequence still committing. |
@@ -803,7 +808,6 @@ xlog_cil_force_lsn( | |||
803 | * before allowing the force of push_seq to go ahead. Hence block | 808 | * before allowing the force of push_seq to go ahead. Hence block |
804 | * on commits for those as well. | 809 | * on commits for those as well. |
805 | */ | 810 | */ |
806 | restart: | ||
807 | spin_lock(&cil->xc_push_lock); | 811 | spin_lock(&cil->xc_push_lock); |
808 | list_for_each_entry(ctx, &cil->xc_committing, committing) { | 812 | list_for_each_entry(ctx, &cil->xc_committing, committing) { |
809 | if (ctx->sequence > sequence) | 813 | if (ctx->sequence > sequence) |
@@ -821,6 +825,28 @@ restart: | |||
821 | /* found it! */ | 825 | /* found it! */ |
822 | commit_lsn = ctx->commit_lsn; | 826 | commit_lsn = ctx->commit_lsn; |
823 | } | 827 | } |
828 | |||
829 | /* | ||
830 | * The call to xlog_cil_push_now() executes the push in the background. | ||
831 | * Hence by the time we have got here it our sequence may not have been | ||
832 | * pushed yet. This is true if the current sequence still matches the | ||
833 | * push sequence after the above wait loop and the CIL still contains | ||
834 | * dirty objects. | ||
835 | * | ||
836 | * When the push occurs, it will empty the CIL and | ||
837 | * atomically increment the currect sequence past the push sequence and | ||
838 | * move it into the committing list. Of course, if the CIL is clean at | ||
839 | * the time of the push, it won't have pushed the CIL at all, so in that | ||
840 | * case we should try the push for this sequence again from the start | ||
841 | * just in case. | ||
842 | */ | ||
843 | |||
844 | if (sequence == cil->xc_current_sequence && | ||
845 | !list_empty(&cil->xc_cil)) { | ||
846 | spin_unlock(&cil->xc_push_lock); | ||
847 | goto restart; | ||
848 | } | ||
849 | |||
824 | spin_unlock(&cil->xc_push_lock); | 850 | spin_unlock(&cil->xc_push_lock); |
825 | return commit_lsn; | 851 | return commit_lsn; |
826 | } | 852 | } |