]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
nfs/localio: refactor iocb and iov_iter_bvec initialization
authorMike Snitzer <snitzer@kernel.org>
Fri, 19 Sep 2025 14:36:27 +0000 (10:36 -0400)
committerAnna Schumaker <anna.schumaker@oracle.com>
Tue, 30 Sep 2025 20:10:30 +0000 (16:10 -0400)
nfs_local_iter_init() is updated to follow the same pattern to
initializing LOCALIO's iov_iter_bvec as was established by
nfsd_iter_read().

Other LOCALIO iocb initialization refactoring in this commit offers
incremental cleanup that will be taken further by the next commit.

No functional change.

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
fs/nfs/localio.c

index b165922e5cb65702477fa79f8ebe53d098401e8b..3b8fa75ce7cdb976186806e6600dd2c791097b09 100644 (file)
@@ -277,23 +277,6 @@ nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred,
 }
 EXPORT_SYMBOL_GPL(nfs_local_open_fh);
 
-static struct bio_vec *
-nfs_bvec_alloc_and_import_pagevec(struct page **pagevec,
-               unsigned int npages, gfp_t flags)
-{
-       struct bio_vec *bvec, *p;
-
-       bvec = kmalloc_array(npages, sizeof(*bvec), flags);
-       if (bvec != NULL) {
-               for (p = bvec; npages > 0; p++, pagevec++, npages--) {
-                       p->bv_page = *pagevec;
-                       p->bv_len = PAGE_SIZE;
-                       p->bv_offset = 0;
-               }
-       }
-       return bvec;
-}
-
 static void
 nfs_local_iocb_free(struct nfs_local_kiocb *iocb)
 {
@@ -310,8 +293,9 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr,
        iocb = kmalloc(sizeof(*iocb), flags);
        if (iocb == NULL)
                return NULL;
-       iocb->bvec = nfs_bvec_alloc_and_import_pagevec(hdr->page_array.pagevec,
-                       hdr->page_array.npages, flags);
+
+       iocb->bvec = kmalloc_array(hdr->page_array.npages,
+                                  sizeof(struct bio_vec), flags);
        if (iocb->bvec == NULL) {
                kfree(iocb);
                return NULL;
@@ -354,14 +338,28 @@ static bool nfs_iov_iter_aligned_bvec(const struct iov_iter *i,
 }
 
 static void
-nfs_local_iter_init(struct iov_iter *i, struct nfs_local_kiocb *iocb, int dir)
+nfs_local_iter_init(struct iov_iter *i, struct nfs_local_kiocb *iocb, int rw)
 {
        struct nfs_pgio_header *hdr = iocb->hdr;
+       struct page **pagevec = hdr->page_array.pagevec;
+       unsigned long v, total;
+       unsigned int base;
+       size_t len;
+
+       v = 0;
+       total = hdr->args.count;
+       base = hdr->args.pgbase;
+       while (total && v < hdr->page_array.npages) {
+               len = min_t(size_t, total, PAGE_SIZE - base);
+               bvec_set_page(&iocb->bvec[v], *pagevec, len, base);
+               total -= len;
+               ++pagevec;
+               ++v;
+               base = 0;
+       }
+       len = hdr->args.count - total;
 
-       iov_iter_bvec(i, dir, iocb->bvec, hdr->page_array.npages,
-                     hdr->args.count + hdr->args.pgbase);
-       if (hdr->args.pgbase != 0)
-               iov_iter_advance(i, hdr->args.pgbase);
+       iov_iter_bvec(i, rw, iocb->bvec, v, len);
 
        if (iocb->kiocb.ki_flags & IOCB_DIRECT) {
                u32 nf_dio_mem_align, nf_dio_offset_align, nf_dio_read_offset_align;
@@ -369,7 +367,7 @@ nfs_local_iter_init(struct iov_iter *i, struct nfs_local_kiocb *iocb, int dir)
                nfs_to->nfsd_file_dio_alignment(iocb->localio, &nf_dio_mem_align,
                                                &nf_dio_offset_align,
                                                &nf_dio_read_offset_align);
-               if (dir == READ)
+               if (rw == ITER_DEST)
                        nf_dio_offset_align = nf_dio_read_offset_align;
 
                if (nf_dio_mem_align && nf_dio_offset_align &&
@@ -490,7 +488,11 @@ static void nfs_local_call_read(struct work_struct *work)
 
        save_cred = override_creds(filp->f_cred);
 
-       nfs_local_iter_init(&iter, iocb, READ);
+       nfs_local_iter_init(&iter, iocb, ITER_DEST);
+       if (iocb->kiocb.ki_flags & IOCB_DIRECT) {
+               iocb->kiocb.ki_complete = nfs_local_read_aio_complete;
+               iocb->aio_complete_work = nfs_local_read_aio_complete_work;
+       }
 
        status = filp->f_op->read_iter(&iocb->kiocb, &iter);
 
@@ -525,11 +527,6 @@ nfs_do_local_read(struct nfs_pgio_header *hdr,
        nfs_local_pgio_init(hdr, call_ops);
        hdr->res.eof = false;
 
-       if (iocb->kiocb.ki_flags & IOCB_DIRECT) {
-               iocb->kiocb.ki_complete = nfs_local_read_aio_complete;
-               iocb->aio_complete_work = nfs_local_read_aio_complete_work;
-       }
-
        INIT_WORK(&iocb->work, nfs_local_call_read);
        queue_work(nfslocaliod_workqueue, &iocb->work);
 
@@ -689,7 +686,11 @@ static void nfs_local_call_write(struct work_struct *work)
        current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO;
        save_cred = override_creds(filp->f_cred);
 
-       nfs_local_iter_init(&iter, iocb, WRITE);
+       nfs_local_iter_init(&iter, iocb, ITER_SOURCE);
+       if (iocb->kiocb.ki_flags & IOCB_DIRECT) {
+               iocb->kiocb.ki_complete = nfs_local_write_aio_complete;
+               iocb->aio_complete_work = nfs_local_write_aio_complete_work;
+       }
 
        file_start_write(filp);
        status = filp->f_op->write_iter(&iocb->kiocb, &iter);
@@ -740,11 +741,6 @@ nfs_do_local_write(struct nfs_pgio_header *hdr,
 
        nfs_set_local_verifier(hdr->inode, hdr->res.verf, hdr->args.stable);
 
-       if (iocb->kiocb.ki_flags & IOCB_DIRECT) {
-               iocb->kiocb.ki_complete = nfs_local_write_aio_complete;
-               iocb->aio_complete_work = nfs_local_write_aio_complete_work;
-       }
-
        INIT_WORK(&iocb->work, nfs_local_call_write);
        queue_work(nfslocaliod_workqueue, &iocb->work);