From: Patrick Farrell Date: Fri, 3 Nov 2023 20:22:22 +0000 (-0400) Subject: EX-7601 ofd: add read lnb to ofd_preprw_write X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=524b17c6ec6be3670f185f367c335ac9562f4571;p=fs%2Flustre-release.git EX-7601 ofd: add read lnb to ofd_preprw_write The read phase of read-modify-write for compressed files needs to read only a subset of the pages which will be written, so it needs a separate set of lnb pointers for tracking this subset. This patch passes around the necessary argument but does not set up or use the lnb yet. Test-Parameters: trivial Signed-off-by: Patrick Farrell Change-Id: I7ec7101e65e73a6c9e67cea3c58d8cace38e70e0 Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52984 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Artem Blagodarenko --- diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 0ddf8e8..44a0538 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1082,8 +1082,9 @@ struct obd_ops { int (*o_preprw)(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *remote, - int *nr_pages, struct niobuf_local *local, - enum ll_compr_type type, int lvl, int chunk_bits); + int *nr_pages, struct niobuf_local *lnb, + struct niobuf_local *lnb2, enum ll_compr_type type, + int lvl, int chunk_bits); int (*o_commitrw)(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 4a899ab..ccd4c6b 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1140,7 +1140,8 @@ static inline int obd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *remote, int *pages, - struct niobuf_local *local, + struct niobuf_local *lnb, + struct niobuf_local *lnb2, enum ll_compr_type type, int lvl, int chunk_bits) { int rc; @@ -1158,7 +1159,7 @@ static inline int obd_preprw(const struct lu_env *env, int cmd, } rc = OBP(exp->exp_obd, preprw)(env, cmd, exp, oa, objcount, obj, remote, - pages, local, type, lvl, chunk_bits); + pages, lnb, lnb2, type, lvl, chunk_bits); RETURN(rc); } diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index d6121b5..5b4a4eb 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -1385,8 +1385,8 @@ static inline char *mdt_req_get_jobid(struct ptlrpc_request *req) int mdt_obd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int *nr_local, - struct niobuf_local *lnb, enum ll_compr_type type, int lvl, - int chunk_bits); + struct niobuf_local *lnb, struct niobuf_local *unused, + enum ll_compr_type type, int lvl, int chunk_bits); int mdt_obd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, diff --git a/lustre/mdt/mdt_io.c b/lustre/mdt/mdt_io.c index 3de19b9..af6514a 100644 --- a/lustre/mdt/mdt_io.c +++ b/lustre/mdt/mdt_io.c @@ -512,8 +512,8 @@ unlock: int mdt_obd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int *nr_local, - struct niobuf_local *lnb, enum ll_compr_type type, int lvl, - int chunk_bits) + struct niobuf_local *lnb, struct niobuf_local *unused, + enum ll_compr_type type, int lvl, int chunk_bits) { struct tgt_session_info *tsi = tgt_ses_info(env); struct mdt_thread_info *info = tsi2mdt_info(tsi); diff --git a/lustre/obdecho/echo.c b/lustre/obdecho/echo.c index 7f5972b..0d4a095 100644 --- a/lustre/obdecho/echo.c +++ b/lustre/obdecho/echo.c @@ -309,7 +309,8 @@ static int echo_preprw(const struct lu_env *env, int cmd, struct obd_export *export, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *nb, int *pages, - struct niobuf_local *res, enum ll_compr_type type, + struct niobuf_local *res, + struct niobuf_local *unused, enum ll_compr_type type, int lvl, int chunk_bits) { struct obd_device *obd; diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 68d9ab8..c0f048a 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -2693,7 +2693,7 @@ static int echo_client_prep_commit(const struct lu_env *env, lpages = npages; ret = obd_preprw(env, rw, exp, oa, 1, &ioo, &rnb, &lpages, lnb, - 0, 0, 0); + NULL, 0, 0, 0); if (ret != 0) GOTO(out, ret); diff --git a/lustre/ofd/ofd_internal.h b/lustre/ofd/ofd_internal.h index 508d968..a01ee27 100644 --- a/lustre/ofd/ofd_internal.h +++ b/lustre/ofd/ofd_internal.h @@ -353,8 +353,8 @@ int ofd_decompress_read(const struct lu_env *env, struct obd_export *exp, int ofd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int *nr_local, - struct niobuf_local *lnb, enum ll_compr_type type, int lvl, - int chunk_bits); + struct niobuf_local *lnb, struct niobuf_local *lnb2, + enum ll_compr_type type, int lvl, int chunk_bits); int ofd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int npages, diff --git a/lustre/ofd/ofd_io.c b/lustre/ofd/ofd_io.c index f98fc46..f9ab71b 100644 --- a/lustre/ofd/ofd_io.c +++ b/lustre/ofd/ofd_io.c @@ -749,8 +749,9 @@ static int ofd_preprw_write(const struct lu_env *env, struct obd_export *exp, struct lu_attr *la, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int *nr_local, - struct niobuf_local *lnb, enum ll_compr_type type, - int lvl, int chunk_bits) + struct niobuf_local *write_lnb, + struct niobuf_local *read_lnb, + enum ll_compr_type type, int lvl, int chunk_bits) { struct range_lock *range = &ofd_info(env)->fti_write_range; struct dt_object *dt_obj = NULL; @@ -928,17 +929,17 @@ static int ofd_preprw_write(const struct lu_env *env, struct obd_export *exp, CDEBUG(D_SEC, "buf_start %llu, buf_end %llu\n", buf_start, buf_end); - rc = dt_bufs_get(env, ofd_object_child(fo), lnb + j, buf_start, + rc = dt_bufs_get(env, ofd_object_child(fo), write_lnb + j, buf_start, buf_len, maxlnb, dbt); if (unlikely(rc < 0)) GOTO(err_nolock, rc); LASSERT(rc <= PTLRPC_MAX_BRW_PAGES); /* correct index for local buffers to continue with */ for (k = 0; k < rc; k++) { - lnb[j+k].lnb_flags = rnb[i].rnb_flags; - lnb[j+k].lnb_flags &= ~OBD_BRW_LOCALS; + write_lnb[j+k].lnb_flags = rnb[i].rnb_flags; + write_lnb[j+k].lnb_flags &= ~OBD_BRW_LOCALS; if (!(rnb[i].rnb_flags & OBD_BRW_GRANTED)) - lnb[j+k].lnb_rc = -ENOSPC; + write_lnb[j+k].lnb_rc = -ENOSPC; } j += rc; *nr_local += rc; @@ -969,12 +970,15 @@ static int ofd_preprw_write(const struct lu_env *env, struct obd_export *exp, } if (compr_unaligned_write) { - rc = dt_read_prep(env, ofd_object_child(fo), lnb, *nr_local, - true); + read_lnb = write_lnb; + + rc = dt_read_prep(env, ofd_object_child(fo), read_lnb, + *nr_local, true); if (unlikely(rc != 0)) GOTO(err, rc); - rc = ofd_decompress_read(env, exp, oa, rnb, lnb, obj, *nr_local, - type, lvl, chunk_bits, true); + rc = ofd_decompress_read(env, exp, oa, rnb, read_lnb, obj, + *nr_local, type, lvl, chunk_bits, + true); if (unlikely(rc != 0)) GOTO(err, rc); /* read_prep sets lnb_rc if it read data, or on error, but the @@ -982,12 +986,12 @@ static int ofd_preprw_write(const struct lu_env *env, struct obd_export *exp, * on error */ for (i = 0; i < *nr_local; i++) { - if (lnb[i].lnb_rc > 0) - lnb[i].lnb_rc = 0; + if (read_lnb[i].lnb_rc > 0) + read_lnb[i].lnb_rc = 0; } } - rc = dt_write_prep(env, ofd_object_child(fo), lnb, *nr_local); + rc = dt_write_prep(env, ofd_object_child(fo), write_lnb, *nr_local); if (unlikely(rc != 0)) GOTO(err, rc); @@ -1029,7 +1033,7 @@ static int ofd_preprw_write(const struct lu_env *env, struct obd_export *exp, err: ofd_read_unlock(env, fo); err_nolock: - dt_bufs_put(env, ofd_object_child(fo), lnb, *nr_local); + dt_bufs_put(env, ofd_object_child(fo), write_lnb, *nr_local); ofd_object_put(env, fo); /* tgt_grant_prepare_write() was called, so we must commit */ tgt_grant_commit(exp, oa->o_grant_used, rc); @@ -1192,6 +1196,7 @@ out: * \param[in] rnb remote buffers * \param[in] nr_local number of local buffers * \param[in] lnb local buffers + * \param[in] lnb2 second set of local buffers, used by preprw_write * \param[in] chunk compression chunk size * * \retval 0 on successful prepare @@ -1200,8 +1205,8 @@ out: int ofd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int *nr_local, - struct niobuf_local *lnb, enum ll_compr_type type, int lvl, - int chunk_bits) + struct niobuf_local *lnb, struct niobuf_local *lnb2, + enum ll_compr_type type, int lvl, int chunk_bits) { struct tgt_session_info *tsi = tgt_ses_info(env); struct ofd_device *ofd = ofd_exp(exp); @@ -1250,8 +1255,8 @@ int ofd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp, if (cmd == OBD_BRW_WRITE) { la_from_obdo(&info->fti_attr, oa, OBD_MD_FLGETATTR); rc = ofd_preprw_write(env, exp, ofd, fid, &info->fti_attr, oa, - objcount, obj, rnb, nr_local, lnb, type, - lvl, chunk_bits); + objcount, obj, rnb, nr_local, lnb, lnb2, + type, lvl, chunk_bits); } else if (cmd == OBD_BRW_READ) { tgt_grant_prepare_read(env, exp, oa); rc = ofd_preprw_read(env, exp, ofd, fid, &info->fti_attr, oa, diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index 1e58a6c..1405c29 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -2541,7 +2541,7 @@ int tgt_brw_read(struct tgt_session_info *tsi) kstart = ktime_get(); rc = obd_preprw(tsi->tsi_env, OBD_BRW_READ, exp, &repbody->oa, 1, - ioo, remote_nb, &npages_local, local_io_nb, + ioo, remote_nb, &npages_local, local_io_nb, NULL, compr_type, compr_lvl, chunk_bits); if (rc != 0) GOTO(out_lock, rc); @@ -2807,7 +2807,8 @@ int tgt_brw_write(struct tgt_session_info *tsi) struct niobuf_remote chunk_lock_rnb; struct ptlrpc_bulk_desc *desc = NULL; struct lustre_handle lockh = {0}; - struct niobuf_local *local_io_nb; + struct niobuf_local *local_write_nb; + struct niobuf_local *local_read_nb; struct niobuf_local *local_tx_nb; struct niobuf_remote *remote_nb; struct ost_body *repbody; @@ -2925,11 +2926,15 @@ int tgt_brw_write(struct tgt_session_info *tsi) CFS_FAIL_TIMEOUT(OBD_FAIL_OST_BRW_PAUSE_PACK, cfs_fail_val); rcs = req_capsule_server_get(&req->rq_pill, &RMF_RCS); - local_io_nb = tbc->tbc_lnb; + local_write_nb = tbc->tbc_lnb; /* by default, the same local iobuf is used for io and transfer. * compression sometimes changes this */ local_tx_nb = tbc->tbc_lnb; + /* compressed writes need a second set of lnb pointers for tracking the + * read they must do for read-modify-write + */ + local_read_nb = tbc->tbc_lnb2; olc = &body->oa.o_layout_compr; compr_type = olc->ol_compr_type; @@ -3017,8 +3022,8 @@ int tgt_brw_write(struct tgt_session_info *tsi) remote_nb[i].rnb_len); kstart = ktime_get(); rc = obd_preprw(tsi->tsi_env, OBD_BRW_WRITE, exp, &repbody->oa, - objcount, ioo, remote_nb, &npages_local, local_io_nb, - compr_type, compr_lvl, chunk_bits); + objcount, ioo, remote_nb, &npages_local, local_write_nb, + local_read_nb, compr_type, compr_lvl, chunk_bits); if (rc < 0) GOTO(out_lock, rc); @@ -3036,7 +3041,7 @@ int tgt_brw_write(struct tgt_session_info *tsi) if (npages_local != npages_remote) { LASSERT(compr_type != LL_COMPR_TYPE_NONE); local_tx_nb = tbc->tbc_lnb2; - io_lnb_to_tx_lnb(local_io_nb, local_tx_nb, remote_nb, + io_lnb_to_tx_lnb(local_write_nb, local_tx_nb, remote_nb, niocount, npages_local); } @@ -3140,8 +3145,8 @@ out_commitrw: /* Must commit after prep above in all cases */ rc = obd_commitrw(tsi->tsi_env, OBD_BRW_WRITE, exp, &repbody->oa, - objcount, ioo, remote_nb, npages_local, local_io_nb, - rc, nob, kstart); + objcount, ioo, remote_nb, npages_local, + local_write_nb, rc, nob, kstart); if (rc == -ENOTCONN) /* quota acquire process has been given up because * either the client has been evicted or the client @@ -3150,7 +3155,7 @@ out_commitrw: no_reply = true; for (i = 0; i < niocount; i++) { - if (!(local_io_nb[i].lnb_flags & OBD_BRW_ASYNC)) { + if (!(local_write_nb[i].lnb_flags & OBD_BRW_ASYNC)) { wait_sync = true; break; }