From: Hugh Dickins <hugh@veritas.com>
To: Kai Makisara <Kai.Makisara@kolumbus.fi>
Cc: James Bottomley <James.Bottomley@SteelEye.com>,
Andrew Morton <akpm@osdl.org>,
linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org
Subject: [PATCH] st: don't doublefree pages from scatterlist
Date: Fri, 3 Feb 2006 19:53:34 +0000 (GMT) [thread overview]
Message-ID: <Pine.LNX.4.61.0602031951280.14829@goblin.wat.veritas.com> (raw)
In-Reply-To: <Pine.LNX.4.61.0602031842290.14065@goblin.wat.veritas.com>
On some architectures, mapping the scatterlist may coalesce entries:
if that coalesced list is then used for freeing the pages afterwards,
there's a danger that pages may be doubly freed (and others leaked).
Fix SCSI Tape's sgl_unmap_user_pages by freeing from the pagelist used
in sgl_map_user_pages. Fixes Ryan Richter's crash on x86_64, with Bad
page state mapcount 2 from sgl_unmap_user_pages, and consequent mayhem.
But it's quite confusing for st's (un)map_user_pages to be named sgl_,
with sg's named st_: while we're changing its arg, rename st's to
st_map_user_pages and st_unmap_user_pages (and do sg's separately).
Signed-off-by: Hugh Dickins <hugh@veritas.com>
---
drivers/scsi/st.c | 20 ++++++++++++--------
drivers/scsi/st.h | 1 +
2 files changed, 13 insertions(+), 8 deletions(-)
--- 2.6.16-rc2/drivers/scsi/st.c 2006-02-03 09:32:25.000000000 +0000
+++ linux/drivers/scsi/st.c 2006-02-03 09:59:37.000000000 +0000
@@ -188,9 +188,9 @@ static int from_buffer(struct st_buffer
static void move_buffer_data(struct st_buffer *, int);
static void buf_to_sg(struct st_buffer *, unsigned int);
-static int sgl_map_user_pages(struct scatterlist *, const unsigned int,
+static int st_map_user_pages(struct st_buffer *, const unsigned int,
unsigned long, size_t, int);
-static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
+static int st_unmap_user_pages(struct st_buffer *, const unsigned int, int);
static int st_probe(struct device *);
static int st_remove(struct device *);
@@ -1404,7 +1404,7 @@ static int setup_buffering(struct scsi_t
if (i && ((unsigned long)buf & queue_dma_alignment(
STp->device->request_queue)) == 0) {
- i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
+ i = st_map_user_pages(STbp, STbp->use_sg,
(unsigned long)buf, count, (is_read ? READ : WRITE));
if (i > 0) {
STbp->do_dio = i;
@@ -1456,7 +1456,7 @@ static void release_buffering(struct scs
STbp = STp->buffer;
if (STbp->do_dio) {
- sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
+ st_unmap_user_pages(STbp, STbp->do_dio, is_read);
STbp->do_dio = 0;
STbp->sg_segs = 0;
}
@@ -4368,13 +4368,14 @@ static void do_create_class_files(struct
}
/* The following functions may be useful for a larger audience. */
-static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
+static int st_map_user_pages(struct st_buffer *STbp, const unsigned int max_pages,
unsigned long uaddr, size_t count, int rw)
{
unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
unsigned long start = uaddr >> PAGE_SHIFT;
const int nr_pages = end - start;
int res, i, j;
+ struct scatterlist *sgl = STbp->sg;
struct page **pages;
/* User attempted Overflow! */
@@ -4434,7 +4435,7 @@ static int sgl_map_user_pages(struct sca
sgl[0].length = count;
}
- kfree(pages);
+ STbp->sg_pages = pages;
return nr_pages;
out_unmap:
@@ -4449,13 +4450,14 @@ static int sgl_map_user_pages(struct sca
/* And unmap them... */
-static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
+static int st_unmap_user_pages(struct st_buffer *STbp, const unsigned int nr_pages,
int dirtied)
{
int i;
+ /* Scatterlist entries may have been coalesced: free saved pagelist */
for (i=0; i < nr_pages; i++) {
- struct page *page = sgl[i].page;
+ struct page *page = STbp->sg_pages[i];
if (dirtied)
SetPageDirty(page);
@@ -4465,5 +4467,7 @@ static int sgl_unmap_user_pages(struct s
page_cache_release(page);
}
+ kfree(STbp->sg_pages);
+ STbp->sg_pages = NULL;
return 0;
}
--- 2.6.16-rc2/drivers/scsi/st.h 2006-02-03 09:32:25.000000000 +0000
+++ linux/drivers/scsi/st.h 2006-02-03 09:59:37.000000000 +0000
@@ -49,6 +49,7 @@ struct st_buffer {
unsigned short frp_segs; /* number of buffer segments */
unsigned int frp_sg_current; /* driver buffer length currently in s/g list */
struct st_buf_fragment *frp; /* the allocated buffer fragment list */
+ struct page **sg_pages; /* pages to be freed from s/g list */
struct scatterlist sg[1]; /* MUST BE last item */
};
next prev parent reply other threads:[~2006-02-03 19:52 UTC|newest]
Thread overview: 99+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20051129092432.0f5742f0.akpm@osdl.org>
2005-11-29 18:34 ` Fw: crash on x86_64 - mm related? Ryan Richter
[not found] ` <Pine.LNX.4.63.0511292147120.5739@kai.makisara.local>
2005-11-29 20:31 ` Ryan Richter
2005-11-29 20:48 ` Kai Makisara
2005-11-29 20:58 ` Ryan Richter
2005-11-29 21:36 ` Kai Makisara
2005-11-30 5:12 ` Kai Makisara
2005-12-01 19:18 ` Kai Makisara
2005-12-01 19:38 ` Linus Torvalds
2005-12-01 19:56 ` Ryan Richter
2005-12-01 20:21 ` Hugh Dickins
2005-12-01 21:44 ` Kai Makisara
2005-12-02 18:03 ` Ryan Richter
2005-12-02 18:43 ` Jesper Juhl
2005-12-02 19:12 ` Hugh Dickins
2005-12-02 19:44 ` Ryan Richter
2005-12-02 20:40 ` Hugh Dickins
2005-12-03 17:29 ` Ryan Richter
2005-12-06 16:08 ` Ryan Richter
2005-12-06 20:31 ` Hugh Dickins
2005-12-06 20:43 ` Ryan Richter
2005-12-07 18:37 ` Hugh Dickins
2005-12-08 2:26 ` Ryan Richter
2005-12-12 16:54 ` Ryan Richter
2005-12-12 17:40 ` Linus Torvalds
2005-12-12 17:45 ` James Bottomley
2005-12-12 18:04 ` Ryan Richter
2005-12-12 18:09 ` Linus Torvalds
2005-12-12 18:24 ` James Bottomley
2005-12-15 19:09 ` Ryan Richter
2005-12-16 4:01 ` James Bottomley
2005-12-17 3:31 ` Ryan Richter
2005-12-26 23:42 ` Ryan Richter
2005-12-27 16:21 ` Kai Makisara
2006-01-03 19:03 ` Ryan Richter
2006-01-04 17:27 ` Ryan Richter
2006-01-04 21:48 ` Kai Makisara
2006-01-05 5:40 ` Ryan Richter
2006-01-05 20:12 ` Ryan Richter
2006-01-05 21:18 ` Linus Torvalds
2006-01-08 22:36 ` Ryan Richter
2006-01-09 3:31 ` Ryan Richter
2006-01-09 4:07 ` Linus Torvalds
2006-01-09 5:13 ` Andrew Morton
2006-01-09 5:45 ` Ryan Richter
2006-01-09 5:57 ` Andrew Morton
2006-01-09 9:44 ` Hugh Dickins
2006-01-09 18:53 ` Ryan Richter
2006-01-09 19:31 ` Hugh Dickins
2006-01-09 20:05 ` Ryan Richter
2006-01-18 0:12 ` Ryan Richter
2006-01-18 16:00 ` Hugh Dickins
2006-02-03 19:46 ` Hugh Dickins
2006-02-03 19:51 ` [PATCH] ib: don't doublefree pages from scatterlist Hugh Dickins
2006-02-03 23:13 ` Roland Dreier
2006-02-03 19:53 ` Hugh Dickins [this message]
2006-02-03 20:38 ` [PATCH] st: " Mike Christie
2006-02-03 21:16 ` Hugh Dickins
2006-02-04 12:10 ` Kai Makisara
2006-02-04 15:01 ` Hugh Dickins
2006-02-03 19:55 ` [PATCH] ipr: " Hugh Dickins
2006-02-03 22:06 ` Brian King
2006-02-04 0:26 ` Hugh Dickins
2006-02-05 21:35 ` Brian King
2006-02-06 9:32 ` Hugh Dickins
2006-02-06 9:46 ` David S. Miller
2006-02-06 14:46 ` Brian King
2006-02-06 16:45 ` Hugh Dickins
2006-02-06 17:38 ` James Bottomley
2006-02-06 19:15 ` Brian King
2006-02-06 21:11 ` Andi Kleen
2006-02-06 21:49 ` David S. Miller
2006-02-06 22:11 ` Hugh Dickins
2006-02-06 22:13 ` Andi Kleen
2006-02-07 3:09 ` Ryan Richter
2006-02-11 22:38 ` Ryan Richter
2006-02-12 18:57 ` Hugh Dickins
2006-02-12 21:29 ` Andi Kleen
2006-02-13 17:21 ` Hugh Dickins
2006-02-06 15:02 ` James Bottomley
2006-02-06 17:01 ` Hugh Dickins
2006-02-03 19:56 ` [PATCH] osst: " Hugh Dickins
2006-02-03 21:10 ` Fw: crash on x86_64 - mm related? Ryan Richter
2006-02-04 11:58 ` Kai Makisara
2006-02-04 14:46 ` Hugh Dickins
2006-01-05 22:09 ` Kai Makisara
2006-01-04 18:26 ` Ryan Richter
2005-12-07 18:30 ` Ryan Richter
2005-12-07 18:56 ` Hugh Dickins
2005-12-07 19:06 ` Ryan Richter
2005-12-06 17:57 ` Ryan Richter
2005-12-01 20:28 ` James Bottomley
2005-12-01 21:17 ` Kai Makisara
2005-12-02 13:45 ` Hugh Dickins
2005-12-02 17:59 ` Kai Makisara
2005-12-02 18:55 ` Hugh Dickins
2005-12-02 19:46 ` Kai Makisara
2005-12-02 20:47 ` Hugh Dickins
2005-12-04 9:29 ` Kai Makisara
2005-12-01 19:53 ` Ryan Richter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.61.0602031951280.14829@goblin.wat.veritas.com \
--to=hugh@veritas.com \
--cc=James.Bottomley@SteelEye.com \
--cc=Kai.Makisara@kolumbus.fi \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®