lkml.org 
[lkml]   [2022]   [Aug]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6/6] fuse: convert direct IO paths to use FOLL_PIN
    Date
    Convert the fuse filesystem to use pin_user_pages_fast() and
    unpin_user_page(), instead of get_user_pages_fast() and put_page().

    Signed-off-by: John Hubbard <jhubbard@nvidia.com>
    ---
    fs/fuse/dev.c | 8 ++++++--
    fs/fuse/file.c | 31 ++++++++++++++++++++-----------
    fs/fuse/fuse_i.h | 1 +
    3 files changed, 27 insertions(+), 13 deletions(-)

    diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
    index 51897427a534..eb841fc82bb9 100644
    --- a/fs/fuse/dev.c
    +++ b/fs/fuse/dev.c
    @@ -675,7 +675,10 @@ static void fuse_copy_finish(struct fuse_copy_state *cs)
    flush_dcache_page(cs->pg);
    set_page_dirty_lock(cs->pg);
    }
    - put_page(cs->pg);
    + if (cs->pipebufs)
    + put_page(cs->pg);
    + else
    + dio_w_unpin_user_page(cs->pg);
    }
    cs->pg = NULL;
    }
    @@ -730,7 +733,8 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
    }
    } else {
    size_t off;
    - err = iov_iter_get_pages2(cs->iter, &page, PAGE_SIZE, 1, &off);
    + err = dio_w_iov_iter_pin_pages(cs->iter, &page, PAGE_SIZE, 1,
    + &off);
    if (err < 0)
    return err;
    BUG_ON(!err);
    diff --git a/fs/fuse/file.c b/fs/fuse/file.c
    index 1a3afd469e3a..a79aa4fea937 100644
    --- a/fs/fuse/file.c
    +++ b/fs/fuse/file.c
    @@ -625,14 +625,19 @@ void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos,
    }

    static void fuse_release_user_pages(struct fuse_args_pages *ap,
    - bool should_dirty)
    + bool should_dirty, bool is_kvec)
    {
    unsigned int i;

    - for (i = 0; i < ap->num_pages; i++) {
    - if (should_dirty)
    - set_page_dirty_lock(ap->pages[i]);
    - put_page(ap->pages[i]);
    + if (is_kvec) {
    + for (i = 0; i < ap->num_pages; i++) {
    + if (should_dirty)
    + set_page_dirty_lock(ap->pages[i]);
    + put_page(ap->pages[i]);
    + }
    + } else {
    + dio_w_unpin_user_pages_dirty_lock(ap->pages, ap->num_pages,
    + should_dirty);
    }
    }

    @@ -733,7 +738,7 @@ static void fuse_aio_complete_req(struct fuse_mount *fm, struct fuse_args *args,
    struct fuse_io_priv *io = ia->io;
    ssize_t pos = -1;

    - fuse_release_user_pages(&ia->ap, io->should_dirty);
    + fuse_release_user_pages(&ia->ap, io->should_dirty, io->is_kvec);

    if (err) {
    /* Nothing */
    @@ -1414,10 +1419,10 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
    while (nbytes < *nbytesp && ap->num_pages < max_pages) {
    unsigned npages;
    size_t start;
    - ret = iov_iter_get_pages2(ii, &ap->pages[ap->num_pages],
    - *nbytesp - nbytes,
    - max_pages - ap->num_pages,
    - &start);
    + ret = dio_w_iov_iter_pin_pages(ii, &ap->pages[ap->num_pages],
    + *nbytesp - nbytes,
    + max_pages - ap->num_pages,
    + &start);
    if (ret < 0)
    break;

    @@ -1483,6 +1488,9 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
    fl_owner_t owner = current->files;
    size_t nbytes = min(count, nmax);

    + /* For use in fuse_release_user_pages(): */
    + io->is_kvec = iov_iter_is_kvec(iter);
    +
    err = fuse_get_user_pages(&ia->ap, iter, &nbytes, write,
    max_pages);
    if (err && !nbytes)
    @@ -1498,7 +1506,8 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
    }

    if (!io->async || nres < 0) {
    - fuse_release_user_pages(&ia->ap, io->should_dirty);
    + fuse_release_user_pages(&ia->ap, io->should_dirty,
    + io->is_kvec);
    fuse_io_free(ia);
    }
    ia = NULL;
    diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
    index 488b460e046f..1d927e499395 100644
    --- a/fs/fuse/fuse_i.h
    +++ b/fs/fuse/fuse_i.h
    @@ -290,6 +290,7 @@ struct fuse_io_priv {
    struct kiocb *iocb;
    struct completion *done;
    bool blocking;
    + bool is_kvec;
    };

    #define FUSE_IO_PRIV_SYNC(i) \
    --
    2.37.2
    \
     
     \ /
      Last update: 2022-08-27 10:38    [W:3.990 / U:1.116 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site