From: Mike Snitzer Date: Fri, 19 Sep 2025 14:36:27 +0000 (-0400) Subject: nfs/localio: refactor iocb and iov_iter_bvec initialization X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=091bdcfcece0963a9a6590ba7cfcc9e1d454165f;p=thirdparty%2Fkernel%2Fstable.git nfs/localio: refactor iocb and iov_iter_bvec initialization 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 Signed-off-by: Anna Schumaker --- diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index b165922e5cb65..3b8fa75ce7cdb 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -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);