On Wed, May 12, 2021 at 03:15:42PM +0200, Christoph Hellwig wrote: > Replace the blk_poll interface that requires the caller to keep a queue > and cookie from the submissions with polling based on the bio. > > Polling for the bio itself leads to a few advantages: > > - the cookie construction can made entirely private in blk-mq.c > - the caller does not need to remember the request_queue and cookie > separately and thus sidesteps their lifetime issues > - keeping the device and the cookie inside the bio allows to trivially > support polling BIOs remapping by stacking drivers > - a lot of code to propagate the cookie back up the submission path can > be removed entirely. > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> ... > + > +/* > + * Helper to implement file_operations.iopoll. Requires the bio to be stored > + * in iocb->private, and cleared before freeing the bio. > + */ > +int iocb_bio_iopoll(struct kiocb *kiocb, unsigned int flags) > +{ > + struct bio *bio; > + int ret = 0; > + > + /* > + * Note: the bio cache only uses SLAB_TYPESAFE_BY_RCU, so bio can > + * point to a freshly allocated bio at this point. If that happens > + * we have a few cases to consider: > + * > + * 1) the bio is beeing initialized and bi_bdev is NULL. We can just > + * simply nothing in this case > + * 2) the bio points to a not poll enabled device. bio_poll will catch > + * this and return 0 > + * 3) the bio points to a poll capable device, including but not > + * limited to the one that the original bio pointed to. In this > + * case we will call into the actual poll method and poll for I/O, > + * even if we don't need to, but it won't cause harm either. > + * > + * For cases 2) and 3) above the RCU grace period ensures that the > + * bi_bdev is still allocated, and because partitions hold a reference > + * to the whole device bdev and thus disk it is still valid. > + */ > + rcu_read_lock(); > + bio = READ_ONCE(kiocb->private); > + if (bio && bio->bi_bdev) > + ret = bio_poll(bio, flags); The bio can be re-allocated from another IO path & bdev after checking on bio->bi_bdev in the above code, then this bio is freed, its ->bi_bdev is freed, same with its associated disk/hw queues/request queue. Both bdev and request queue are freed via rcu, but disk/hw queues are freed immediately, so there is still UAF risk in bio_poll(). Thanks, Ming