Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ublk: don't mutate struct bio_vec in iteration

__bio_for_each_segment() uses the returned struct bio_vec's bv_len field
to advance the struct bvec_iter at the end of each loop iteration. So
it's incorrect to modify it during the loop. Don't assign to bv_len (or
bv_offset, for that matter) in ublk_copy_user_pages().

Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Fixes: e87d66ab27ac ("ublk: use rq_for_each_segment() for user copy")
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Caleb Sander Mateos and committed by
Jens Axboe
db339b40 cfdeb588

+6 -6
+6 -6
drivers/block/ublk_drv.c
··· 926 926 size_t done = 0; 927 927 928 928 rq_for_each_segment(bv, req, iter) { 929 + unsigned len; 929 930 void *bv_buf; 930 931 size_t copied; 931 932 ··· 935 934 continue; 936 935 } 937 936 938 - bv.bv_offset += offset; 939 - bv.bv_len -= offset; 940 - bv_buf = bvec_kmap_local(&bv); 937 + len = bv.bv_len - offset; 938 + bv_buf = kmap_local_page(bv.bv_page) + bv.bv_offset + offset; 941 939 if (dir == ITER_DEST) 942 - copied = copy_to_iter(bv_buf, bv.bv_len, uiter); 940 + copied = copy_to_iter(bv_buf, len, uiter); 943 941 else 944 - copied = copy_from_iter(bv_buf, bv.bv_len, uiter); 942 + copied = copy_from_iter(bv_buf, len, uiter); 945 943 946 944 kunmap_local(bv_buf); 947 945 948 946 done += copied; 949 - if (copied < bv.bv_len) 947 + if (copied < len) 950 948 break; 951 949 952 950 offset = 0;