>>>>> Stephen C Tweedie (SCT) writes: >> + /* return credit back to the handle if it was really spent */ >> + if (credits) { >> + handle->h_buffer_credits++; >> + spin_lock(&handle->h_transaction->t_handle_lock); >> + handle->h_transaction->t_outstanding_credits++; >> + spin_lock(&handle->h_transaction->t_handle_lock); >> + }
SCT> That returns the credit to A (satisfying ext3), but you just grew SCT> t_outstanding_credits, thus growing the journal commitments without SCT> checking if it's safe to do so or being able to handle failure. So it SCT> just reintroduces the original bug. incremented h_buffer_credits will be subtracted from incremented t_outstanding_credits in journal_stop(). so, there is no imbalance at this point. then, if (b_tcount == 0) we can correct t_outstanind_credits or h_buffer_credits. wrong? let's try another way ... we have two processes: P1 and P2. they access block B. the code is: if (credits != 0) { handle->h_buffer_credits++; transaction->t_outstanding_credits++; } if (jh->b_tcount == 0) transcation->t_outstanding_credits--; case 1: P1 accesses B (*credits=1) P1 releases B (credits != 0) h1->h_buffer_credits++; (credits != 0) transaction->t_outstanding_credits++; (b_tcount == 0) transaction->t_outstanding_credits--; OUTPUT: transaction->t_outstanding_credits -= 1 case 2: P1 accesses B (*credits=1) P2 accesses B (*credits=0) P1 releases B P2 modifies B (credits != 0) h1->h_buffer_credits++; (credits != 0) transaction->t_outstainding_credits++; (b_tcount != 0) OUTPUT: journal_stop() will subtract incremented h_buffer_credits from incremented t_outstading_credits => no changes case 3: P1 accesses B (*credits=1) P2 accesses B (*credits=0) P2 releases B P1 modifies B (credits != 0) (credits != 0) (b_tcount == 0) OUTPUT: no changes case 4: P1 accesses B (*credits=1) P2 accesses B (*credits=0) P2 releases B P1 releases B (credits != 0) (credits != 0) (b_tcount == 0) (credits != 0) h1->h_buffer_credits++; (credits != 0) transaction->t_outstanding_credits++; (b_tcount == 0) transaction->t_outstanding_credits--; OUTPUT: P2 will change nothing, P1 will drop the buffer and correct t_outstanding_credits case 5: P1 accesses B (*credits=1) P2 accesses B (*credits=0) P1 releases B P2 releases B (credits != 0) h1->h_buffer_credits++; (credits != 0) transaction->t_outstanding_credits++; (b_tcount == 0) (credits != 0) (credits != 0) (b_tcount == 0) transaction->t_outstanding_credits--; OUTPUT: P1 will change own credits, P2 will drop the buffer and correct t_outstanding_credits thanks, Alex - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/