diff options
author | Steven Rostedt (Red Hat) <rostedt@goodmis.org> | 2013-09-12 23:30:18 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-09-12 23:30:18 -0400 |
commit | 3cc4110d80c3b2d90ea90ff849bf744c514a366c (patch) | |
tree | 5dbc90c6d95eaf45c820d5943bd2472dbb855291 /fs/bio.c | |
parent | 110c3bc0a80e279d94954b0f65ea0869a4952445 (diff) | |
parent | 03188ddd7dd3fdc65d626ac8bb9d1851502263c5 (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.c | 20 |
1 files changed, 15 insertions, 5 deletions
@@ -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; |