From 652032d6c18caffc0782d49e5d5e373010f2bc61 Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Sun, 2 Jun 2024 12:02:45 -0400 Subject: [PATCH] LU-14992 mdt: restore mkdir VBR support The patch of LU-14470 (striped mkdir replay by client request) broke the mkdir VBR support: in mkdir replay, if target exists, it should do version check instead of return -EEXIST directly, otherwise the VBR support is broken. Fixes: a2e997f0be ("LU-14470 dne: striped mkdir replay by client request") Signed-off-by: Lai Siyao Change-Id: I858499f3ef5315bbce9538733400cf6102675e4c Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55714 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_reint.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index d674fa3..e123f00 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -593,14 +593,9 @@ static int mdt_create(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) rc = mdo_lookup(info->mti_env, mdt_object_child(parent), &rr->rr_name, &info->mti_tmp_fid1, &info->mti_spec); if (rc == 0) { - /* mkdir may be partially executed: name entry was successfully - * inserted into parent diretory on remote MDT, while target not - * created on local MDT. This happens when update log recovery - * is aborted, and mkdir is replayed by client request. - */ - if (unlikely(!(info->mti_spec.sp_replay && - mdt_object_remote(parent)) && - !restripe)) + bool child_exists = false; + + if (unlikely(!info->mti_spec.sp_replay && !restripe)) GOTO(put_parent, rc = -EEXIST); child = mdt_object_find(info->mti_env, info->mti_mdt, @@ -608,15 +603,34 @@ static int mdt_create(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) if (unlikely(IS_ERR(child))) GOTO(put_parent, rc = PTR_ERR(child)); - if (mdt_object_exists(child)) { - mdt_object_put(info->mti_env, child); - rc = -EEXIST; - if (restripe) + child_exists = mdt_object_exists(child); + mdt_object_put(info->mti_env, child); + if (child_exists) { + if (restripe) { rc = mdt_restripe(info, parent, &rr->rr_name, rr->rr_fid2, spec, ma); + } else { + LASSERT(info->mti_spec.sp_replay); + mdt_obj_version_get(info, child, + &info->mti_ver[1]); + rc = mdt_version_check(mdt_info_req(info), + info->mti_ver[1], 1); + } GOTO(put_parent, rc); + } else if (restripe) { + /* restripe, dirent exists but inode not */ + GOTO(put_parent, rc = -EINVAL); + } else if (!mdt_object_remote(parent)) { + /* create, parent is on local MDT and dirent exists */ + LASSERT(info->mti_spec.sp_replay); + GOTO(put_parent, rc = -EEXIST); } - mdt_object_put(info->mti_env, child); + /* mkdir may be partially executed: name entry was successfully + * inserted into parent diretory on remote MDT, while target not + * created on local MDT. This happens when update log recovery + * is aborted, and mkdir is replayed by client request. + */ + LASSERT(info->mti_spec.sp_replay && !child_exists && !restripe); recreate_obj = true; } else if (rc != -ENOENT) { GOTO(put_parent, rc); -- 1.8.3.1