Skip to content

Commit 21d706d

Browse files
committed
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
1 parent 92b6cc5 commit 21d706d

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

fs/netfs/objects.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static void netfs_free_request(struct work_struct *work)
7676
{
7777
struct netfs_io_request *rreq =
7878
container_of(work, struct netfs_io_request, work);
79+
unsigned int i;
7980

8081
trace_netfs_rreq(rreq, netfs_rreq_trace_free);
8182
netfs_proc_del_rreq(rreq);
@@ -84,6 +85,15 @@ static void netfs_free_request(struct work_struct *work)
8485
rreq->netfs_ops->free_request(rreq);
8586
if (rreq->cache_resources.ops)
8687
rreq->cache_resources.ops->end_operation(&rreq->cache_resources);
88+
if (rreq->direct_bv) {
89+
for (i = 0; i < rreq->direct_bv_count; i++) {
90+
if (rreq->direct_bv[i].bv_page) {
91+
if (rreq->direct_bv_unpin)
92+
unpin_user_page(rreq->direct_bv[i].bv_page);
93+
}
94+
}
95+
kvfree(rreq->direct_bv);
96+
}
8797
kfree_rcu(rreq, rcu);
8898
netfs_stat_d(&netfs_n_rh_rreq);
8999
}

include/linux/netfs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,16 @@ struct netfs_io_request {
190190
struct iov_iter iter; /* Unencrypted-side iterator */
191191
struct iov_iter io_iter; /* I/O (Encrypted-side) iterator */
192192
void *netfs_priv; /* Private data for the netfs */
193+
struct bio_vec *direct_bv; /* DIO buffer list (when handling iovec-iter) */
194+
unsigned int direct_bv_count; /* Number of elements in direct_bv[] */
193195
unsigned int debug_id;
194196
atomic_t nr_outstanding; /* Number of ops in progress */
195197
atomic_t nr_copy_ops; /* Number of copy-to-cache ops in progress */
196198
size_t submitted; /* Amount submitted for I/O so far */
197199
size_t len; /* Length of the request */
198200
short error; /* 0 or error that occurred */
199201
enum netfs_io_origin origin; /* Origin of the request */
202+
bool direct_bv_unpin; /* T if direct_bv[] must be unpinned */
200203
loff_t i_size; /* Size of the file */
201204
loff_t start; /* Start position */
202205
pgoff_t no_unlock_folio; /* Don't unlock this folio after read */

0 commit comments

Comments
 (0)