On Mon, May 18, 2009 at 06:00:12PM -0700, Dan Williams wrote: > +/** > + * async_raid6_2data_recov - asynchronously calculate two missing data blocks > + * @disks: number of disks in the RAID-6 array > + * @bytes: block size > + * @faila: first failed drive index > + * @failb: second failed drive index > + * @blocks: array of source pointers where the last two entries are p and q > + * @submit: submission/completion modifiers > + */ > +struct dma_async_tx_descriptor * > +async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb, > + struct page **blocks, struct async_submit_ctl *submit) > +{ [...] > + /* Dx = A*(P+Pxy) + B*(Q+Qxy) */ > + srcs[0] = dp; > + srcs[1] = dq; > + coef[0] = raid6_gfexi[failb-faila]; Here it's essential that faila < failb. This should either be clearly documented and checked for, or (better) the function should swap faila and failb if they are in the wrong order. > + p = blocks[disks-2]; > + q = blocks[disks-1]; > + > + /* Compute syndrome with zero for the missing data page > + Use the dead data page as temporary storage for delta q */ > + dq = blocks[faila]; > + blocks[faila] = (void *)raid6_empty_zero_page; > + blocks[disks-1] = dq; > + > + submit->flags &= ~ASYNC_TX_ACK; > + submit->cb_fn = NULL; > + submit->cb_param = NULL; > + tx = async_gen_syndrome(blocks, 0, disks, bytes, submit); > + submit->depend_tx = tx; > + > + /* Restore pointer table */ > + blocks[faila] = dq; > + blocks[disks-1] = q; > + > + /* Now, pick the proper data tables */ > + coef = raid6_gfinv[raid6_gfexp[faila]]; Pick data tables? The formula for recovering the data block is (q + dq) / g^faila (with g being the generator). What this line actually does is computing g^{-faila}. Regards Andre -- The only person who always got his work done by Friday was Robinson Crusoe
Attachment:
signature.asc
Description: Digital signature