From c982c368bb90adbd312faa05d0cfd842e9ab45a7 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 26 Nov 2009 09:24:13 +0900 Subject: [SCSI] st: fix mdata->page_order handling dio transfer always resets mdata->page_order to zero. It breaks high-order pages previously allocated for non-dio transfer. This patches adds reserved_page_order to st_buffer structure to save page order for non-dio transfer. http://bugzilla.kernel.org/show_bug.cgi?id=14563 When enlarge_buffer() allocates 524288 from 0, st uses six-order page allocation. So mdata->page_order is 6 and frp_seg is 2. After that, if st uses dio, sgl_map_user_pages() sets mdata->page_order to 0 for st_do_scsi(). After that, when we call normalize_buffer(), it frees only free frp_seg * PAGE_SIZE (2 * 4096) though we should free frp_seg * PAGE_SIZE << 6 (2 * 4096 << 6). So we see buffer_size is set to 516096 (524288 - 8192). Reported-by: Joachim Breuer Tested-by: Joachim Breuer Acked-by: Kai Makisara Signed-off-by: FUJITA Tomonori Cc: stable@kernel.org Signed-off-by: James Bottomley --- drivers/scsi/st.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/st.h') diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 544dc6b1f548..f91a67c6d968 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -46,6 +46,7 @@ struct st_buffer { struct st_request *last_SRpnt; struct st_cmdstatus cmdstat; struct page **reserved_pages; + int reserved_page_order; struct page **mapped_pages; struct rq_map_data map_data; unsigned char *b_data; -- cgit v1.2.1