On 10/27/2023 11:49 PM, Keith Busch wrote: > +int bio_integrity_map_user(struct bio *bio, void __user *ubuf, unsigned int len, > + u32 seed) > +{ > + struct request_queue *q = bdev_get_queue(bio->bi_bdev); > + unsigned long offs, align = q->dma_pad_mask | queue_dma_alignment(q); > + int ret, direction, nr_vecs, i, j, folios = 0; > + struct bio_vec stack_vec[UIO_FASTIOV]; > + struct bio_vec bv, *bvec = stack_vec; > + struct page *stack_pages[UIO_FASTIOV]; > + struct page **pages = stack_pages; > + struct bio_integrity_payload *bip; > + struct iov_iter iter; > + struct bvec_iter bi; > + u32 bytes; > + > + if (bio_integrity(bio)) > + return -EINVAL; > + if (len >> SECTOR_SHIFT > queue_max_hw_sectors(q)) > + return -E2BIG; > + > + if (bio_data_dir(bio) == READ) > + direction = ITER_DEST; > + else > + direction = ITER_SOURCE; > + > + iov_iter_ubuf(&iter, direction, ubuf, len); > + nr_vecs = iov_iter_npages(&iter, BIO_MAX_VECS + 1); > + if (nr_vecs > BIO_MAX_VECS) > + return -E2BIG; > + if (nr_vecs > UIO_FASTIOV) { > + bvec = kcalloc(sizeof(*bvec), nr_vecs, GFP_KERNEL); > + if (!bvec) > + return -ENOMEM; > + pages = NULL; > + } > + > + bytes = iov_iter_extract_pages(&iter, &pages, len, nr_vecs, 0, &offs); > + if (unlikely(bytes < 0)) { > + ret = bytes; > + goto free_bvec; > + } > + > + for (i = 0; i < nr_vecs; i = j) { > + size_t size = min_t(size_t, bytes, PAGE_SIZE - offs); > + struct folio *folio = page_folio(pages[i]); > + > + bytes -= size; > + for (j = i + 1; j < nr_vecs; j++) { > + size_t next = min_t(size_t, PAGE_SIZE, bytes); > + > + if (page_folio(pages[j]) != folio || > + pages[j] != pages[j - 1] + 1) > + break; > + unpin_user_page(pages[j]); Is this unpin correct here?