aboutsummaryrefslogtreecommitdiff
path: root/fs/bio.c
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2013-09-12 23:30:18 -0400
committerSteven Rostedt <rostedt@goodmis.org>2013-09-12 23:30:18 -0400
commit3cc4110d80c3b2d90ea90ff849bf744c514a366c (patch)
tree5dbc90c6d95eaf45c820d5943bd2472dbb855291 /fs/bio.c
parent110c3bc0a80e279d94954b0f65ea0869a4952445 (diff)
parent03188ddd7dd3fdc65d626ac8bb9d1851502263c5 (diff)
Merge tag 'v3.0.95' into v3.0-rt
This is the 3.0.95 stable release
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/bio.c b/fs/bio.c
index 9bfade8a609b..5a480440f370 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -786,12 +786,22 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
int bio_uncopy_user(struct bio *bio)
{
struct bio_map_data *bmd = bio->bi_private;
- int ret = 0;
+ struct bio_vec *bvec;
+ int ret = 0, i;
- if (!bio_flagged(bio, BIO_NULL_MAPPED))
- ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
- bmd->nr_sgvecs, bio_data_dir(bio) == READ,
- 0, bmd->is_our_pages);
+ if (!bio_flagged(bio, BIO_NULL_MAPPED)) {
+ /*
+ * if we're in a workqueue, the request is orphaned, so
+ * don't copy into a random user address space, just free.
+ */
+ if (current->mm)
+ ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
+ bmd->nr_sgvecs, bio_data_dir(bio) == READ,
+ 0, bmd->is_our_pages);
+ else if (bmd->is_our_pages)
+ __bio_for_each_segment(bvec, bio, i, 0)
+ __free_page(bvec->bv_page);
+ }
bio_free_map_data(bmd);
bio_put(bio);
return ret;