netfs: Add support for DIO buffering
Add a bvec array pointer and an iterator to netfs_io_request for either holding a copy of a DIO iterator or a list of all the bits of buffer pointed to by a DIO iterator. There are two problems: Firstly, if an iovec-class iov_iter is passed to ->read_iter() or ->write_iter(), this cannot be passed directly to kernel_sendmsg() or kernel_recvmsg() as that may cause locking recursion if a fault is generated, so we need to keep track of the pages involved separately. Secondly, if the I/O is asynchronous, we must copy the iov_iter describing the buffer before returning to the caller as it may be immediately deallocated. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org
This commit is contained in:
@@ -76,6 +76,7 @@ static void netfs_free_request(struct work_struct *work)
|
||||
{
|
||||
struct netfs_io_request *rreq =
|
||||
container_of(work, struct netfs_io_request, work);
|
||||
unsigned int i;
|
||||
|
||||
trace_netfs_rreq(rreq, netfs_rreq_trace_free);
|
||||
netfs_proc_del_rreq(rreq);
|
||||
@@ -84,6 +85,15 @@ static void netfs_free_request(struct work_struct *work)
|
||||
rreq->netfs_ops->free_request(rreq);
|
||||
if (rreq->cache_resources.ops)
|
||||
rreq->cache_resources.ops->end_operation(&rreq->cache_resources);
|
||||
if (rreq->direct_bv) {
|
||||
for (i = 0; i < rreq->direct_bv_count; i++) {
|
||||
if (rreq->direct_bv[i].bv_page) {
|
||||
if (rreq->direct_bv_unpin)
|
||||
unpin_user_page(rreq->direct_bv[i].bv_page);
|
||||
}
|
||||
}
|
||||
kvfree(rreq->direct_bv);
|
||||
}
|
||||
kfree_rcu(rreq, rcu);
|
||||
netfs_stat_d(&netfs_n_rh_rreq);
|
||||
}
|
||||
|
Reference in New Issue
Block a user