From: Christophe Saout - After calling scatterwalk_copychunks walk_in might point to the next page which will break scatterwalk_samebuf (in this case src_p should point to tmp_src anyway and scatterwalk_samembuf returns 0). - scatterwalk_samebuf should also check for equal offsets inside the page (just bad for performance in some cases). --- 25-akpm/crypto/cipher.c | 7 ++++--- 25-akpm/crypto/scatterwalk.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff -puN crypto/cipher.c~crypto-scatterwalk-fixes crypto/cipher.c --- 25/crypto/cipher.c~crypto-scatterwalk-fixes Thu May 20 16:15:24 2004 +++ 25-akpm/crypto/cipher.c Thu May 20 16:15:24 2004 @@ -68,19 +68,20 @@ static int crypt(struct crypto_tfm *tfm, for(;;) { u8 *src_p, *dst_p; + int in_place; scatterwalk_map(&walk_in, 0); scatterwalk_map(&walk_out, 1); src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src); dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst); + in_place = scatterwalk_samebuf(&walk_in, &walk_out, + src_p, dst_p); nbytes -= bsize; scatterwalk_copychunks(src_p, &walk_in, bsize, 0); - prfn(tfm, dst_p, src_p, crfn, enc, info, - scatterwalk_samebuf(&walk_in, &walk_out, - src_p, dst_p)); + prfn(tfm, dst_p, src_p, crfn, enc, info, in_place); scatterwalk_done(&walk_in, 0, nbytes); diff -puN crypto/scatterwalk.h~crypto-scatterwalk-fixes crypto/scatterwalk.h --- 25/crypto/scatterwalk.h~crypto-scatterwalk-fixes Thu May 20 16:15:24 2004 +++ 25-akpm/crypto/scatterwalk.h Thu May 20 16:15:24 2004 @@ -38,6 +38,7 @@ static inline int scatterwalk_samebuf(st void *src_p, void *dst_p) { return walk_in->page == walk_out->page && + walk_in->offset == walk_out->offset && walk_in->data == src_p && walk_out->data == dst_p; } _