Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6c55be8b962f1bdc592d579e81fc27b11ea53dfc
Commit:     6c55be8b962f1bdc592d579e81fc27b11ea53dfc
Parent:     5b23dbe8173c212d6a326e35347b038705603d39
Author:     Dan Williams <[EMAIL PROTECTED]>
AuthorDate: Wed Nov 14 16:59:35 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Nov 14 18:45:39 2007 -0800

    raid5: fix unending write sequence
    
    <debug output from Joel's system>
    handling stripe 7629696, state=0x14 cnt=1, pd_idx=2 ops=0:0:0
    check 5: state 0x6 toread 0000000000000000 read 0000000000000000 write 
fffff800ffcffcc0 written 0000000000000000
    check 4: state 0x6 toread 0000000000000000 read 0000000000000000 write 
fffff800fdd4e360 written 0000000000000000
    check 3: state 0x1 toread 0000000000000000 read 0000000000000000 write 
0000000000000000 written 0000000000000000
    check 2: state 0x1 toread 0000000000000000 read 0000000000000000 write 
0000000000000000 written 0000000000000000
    check 1: state 0x6 toread 0000000000000000 read 0000000000000000 write 
fffff800ff517e40 written 0000000000000000
    check 0: state 0x6 toread 0000000000000000 read 0000000000000000 write 
fffff800fd4cae60 written 0000000000000000
    locked=4 uptodate=2 to_read=0 to_write=4 failed=0 failed_num=0
    for sector 7629696, rmw=0 rcw=0
    </debug>
    
    These blocks were prepared to be written out, but were never handled in
    ops_run_biodrain(), so they remain locked forever.  The operations flags
    are all clear which means handle_stripe() thinks nothing else needs to be
    done.
    
    This state suggests that the STRIPE_OP_PREXOR bit was sampled 'set' when it
    should not have been.  This patch cleans up cases where the code looks at
    sh->ops.pending when it should be looking at the consistent stack-based
    snapshot of the operations flags.
    
    Report from Joel:
        Resync done. Patch fix this bug.
    
    Signed-off-by: Dan Williams <[EMAIL PROTECTED]>
    Tested-by: Joel Bertrand <[EMAIL PROTECTED]>
    Cc: <[EMAIL PROTECTED]>
    Cc: Neil Brown <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 drivers/md/raid5.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 1cfc984..a5aad8c 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -688,7 +688,8 @@ ops_run_prexor(struct stripe_head *sh, struct 
dma_async_tx_descriptor *tx)
 }
 
 static struct dma_async_tx_descriptor *
-ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
+ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
+                unsigned long pending)
 {
        int disks = sh->disks;
        int pd_idx = sh->pd_idx, i;
@@ -696,7 +697,7 @@ ops_run_biodrain(struct stripe_head *sh, struct 
dma_async_tx_descriptor *tx)
        /* check if prexor is active which means only process blocks
         * that are part of a read-modify-write (Wantprexor)
         */
-       int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending);
+       int prexor = test_bit(STRIPE_OP_PREXOR, &pending);
 
        pr_debug("%s: stripe %llu\n", __FUNCTION__,
                (unsigned long long)sh->sector);
@@ -773,7 +774,8 @@ static void ops_complete_write(void *stripe_head_ref)
 }
 
 static void
-ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
+ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
+               unsigned long pending)
 {
        /* kernel stack size limits the total number of disks */
        int disks = sh->disks;
@@ -781,7 +783,7 @@ ops_run_postxor(struct stripe_head *sh, struct 
dma_async_tx_descriptor *tx)
 
        int count = 0, pd_idx = sh->pd_idx, i;
        struct page *xor_dest;
-       int prexor = test_bit(STRIPE_OP_PREXOR, &sh->ops.pending);
+       int prexor = test_bit(STRIPE_OP_PREXOR, &pending);
        unsigned long flags;
        dma_async_tx_callback callback;
 
@@ -808,7 +810,7 @@ ops_run_postxor(struct stripe_head *sh, struct 
dma_async_tx_descriptor *tx)
        }
 
        /* check whether this postxor is part of a write */
-       callback = test_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending) ?
+       callback = test_bit(STRIPE_OP_BIODRAIN, &pending) ?
                ops_complete_write : ops_complete_postxor;
 
        /* 1/ if we prexor'd then the dest is reused as a source
@@ -896,12 +898,12 @@ static void raid5_run_ops(struct stripe_head *sh, 
unsigned long pending)
                tx = ops_run_prexor(sh, tx);
 
        if (test_bit(STRIPE_OP_BIODRAIN, &pending)) {
-               tx = ops_run_biodrain(sh, tx);
+               tx = ops_run_biodrain(sh, tx, pending);
                overlap_clear++;
        }
 
        if (test_bit(STRIPE_OP_POSTXOR, &pending))
-               ops_run_postxor(sh, tx);
+               ops_run_postxor(sh, tx, pending);
 
        if (test_bit(STRIPE_OP_CHECK, &pending))
                ops_run_check(sh);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to