lkml.org 
[lkml]   [2023]   [Dec]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 13/59] netfs: Add support for DIO buffering
    Date
    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>
    cc: Jeff Layton <jlayton@kernel.org>
    cc: linux-cachefs@redhat.com
    cc: linux-fsdevel@vger.kernel.org
    cc: linux-mm@kvack.org
    ---
    fs/netfs/objects.c | 10 ++++++++++
    include/linux/netfs.h | 4 ++++
    2 files changed, 14 insertions(+)

    diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c
    index 1bd20bdad983..4df5e5eeada6 100644
    --- a/fs/netfs/objects.c
    +++ b/fs/netfs/objects.c
    @@ -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);
    }
    diff --git a/include/linux/netfs.h b/include/linux/netfs.h
    index 3da962e977f5..bbb33ccbf719 100644
    --- a/include/linux/netfs.h
    +++ b/include/linux/netfs.h
    @@ -190,6 +190,9 @@ 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) */
    + __counted_by(direct_bv_count);
    + 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 +200,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 */
    \
     
     \ /
      Last update: 2023-12-07 22:26    [W:2.279 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site