From 86f1d9e11124116bbbea60ee0599b75623b7b01f Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Tue, 14 Feb 2023 13:47:54 -0500 Subject: [PATCH] LU-13805 llite: unaligned direct_rw_pages Add support for ll_direct_rw_pages to handle unaligned IO by allowing both the first and last page to be partial pages. This has been broken off from the main unaligned DIO patch to make it more reviewable. Signed-off-by: Patrick Farrell Change-Id: I055105589d5416fe6aa82fb6a087db7b8b38c8d1 --- lustre/llite/rw26.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index 3a5c85d..ed009f8 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -372,20 +372,23 @@ ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, size_t size, struct cl_sync_io *anchor = &sdio->csd_sync; loff_t offset = pv->ldp_file_offset; int io_pages = 0; - int i; ssize_t rc = 0; + int i = 0; ENTRY; cl_2queue_init(queue); - for (i = 0; i < pv->ldp_count; i++) { - LASSERT(!(offset & (PAGE_SIZE - 1))); + while (size > 0) { + size_t from = offset & ~PAGE_MASK; + size_t to = min(from + size, PAGE_SIZE); + page = cl_page_find(env, obj, offset >> PAGE_SHIFT, pv->ldp_pages[i], CPT_TRANSIENT); if (IS_ERR(page)) { rc = PTR_ERR(page); break; } + LASSERT(page->cp_type == CPT_TRANSIENT); rc = cl_page_own(env, io, page); if (rc) { @@ -409,16 +412,24 @@ ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io, size_t size, */ cl_page_list_add(&queue->c2_qin, page, false); /* - * Set page clip to tell transfer formation engine - * that page has to be sent even if it is beyond KMS. + * Call page clip for incomplete pages, to set range of bytes + * in the page and to tell transfer formation engine to send + * the page even if it is beyond KMS (ie, don't trim IO to KMS) */ - if (size < PAGE_SIZE) - cl_page_clip(env, page, 0, size); + if (from != 0 || to != PAGE_SIZE) + cl_page_clip(env, page, from, to); ++io_pages; + i++; - offset += PAGE_SIZE; - size -= PAGE_SIZE; + offset += to - from; + size -= to - from; } + /* on success, we should hit every page in the pvec and have no bytes + * left in 'size' + */ + LASSERT(ergo(rc == 0, i == pv->ldp_count)); + LASSERT(ergo(rc == 0, size == 0)); + if (rc == 0 && io_pages > 0) { int iot = rw == READ ? CRT_READ : CRT_WRITE; -- 1.8.3.1