mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
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:
parent
92b6cc5d1e
commit
21d706d5cf
@ -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);
|
||||
}
|
||||
|
@ -190,6 +190,8 @@ struct netfs_io_request {
|
||||
struct iov_iter iter; /* Unencrypted-side iterator */
|
||||
struct iov_iter io_iter; /* I/O (Encrypted-side) iterator */
|
||||
void *netfs_priv; /* Private data for the netfs */
|
||||
struct bio_vec *direct_bv; /* DIO buffer list (when handling iovec-iter) */
|
||||
unsigned int direct_bv_count; /* Number of elements in direct_bv[] */
|
||||
unsigned int debug_id;
|
||||
atomic_t nr_outstanding; /* Number of ops in progress */
|
||||
atomic_t nr_copy_ops; /* Number of copy-to-cache ops in progress */
|
||||
@ -197,6 +199,7 @@ struct netfs_io_request {
|
||||
size_t len; /* Length of the request */
|
||||
short error; /* 0 or error that occurred */
|
||||
enum netfs_io_origin origin; /* Origin of the request */
|
||||
bool direct_bv_unpin; /* T if direct_bv[] must be unpinned */
|
||||
loff_t i_size; /* Size of the file */
|
||||
loff_t start; /* Start position */
|
||||
pgoff_t no_unlock_folio; /* Don't unlock this folio after read */
|
||||
|
Loading…
Reference in New Issue
Block a user