From 732ed22bdb6ca6abe8896f24e7ba46eea3fc379d Mon Sep 17 00:00:00 2001 From: Mikhail Pershin Date: Tue, 7 Jan 2020 12:49:20 +0300 Subject: [PATCH] LU-13115 mdt: handle mdt_pack_sectx_in_reply() errors The mdt_pack_secctx_in_reply() contains mo_xattr_get() call which -ENOENT error should be checked and exit by error path if needed. In DNE environment lu_object may lost its LOHA_EXISTS flag during osp_xattr_get() and that should be handled to don't proceed with code paths for existent objects. Test-Parameters: clientselinux mdtcount=4 envdefinitions=ONLY=185a testlist=sanity,sanity,sanity,sanity Test-Parameters: clientselinux mdtcount=4 testlist=sanity,recovery-small,sanity-sec Test-Parameters: clientselinux mdtcount=4 testgroup=review-dne-selinux Signed-off-by: Mikhail Pershin Change-Id: I55ad666f58dd3fae3ed097018aa23ed94818d246 Reviewed-on: https://review.whamcloud.com/37148 Reviewed-by: Sebastien Buisson Tested-by: jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_handler.c | 32 +++++++++++++++++++------------- lustre/mdt/mdt_internal.h | 4 ++-- lustre/mdt/mdt_lib.c | 15 ++++++++++++--- lustre/mdt/mdt_open.c | 8 ++++++-- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index a2ffa2c..e2397cf 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -1735,11 +1735,14 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info, } rc = mdt_getattr_internal(info, child, 0); - if (unlikely(rc != 0)) + if (unlikely(rc != 0)) { mdt_object_unlock(info, child, lhc, 1); + RETURN(rc); + } - mdt_pack_secctx_in_reply(info, child); - + rc = mdt_pack_secctx_in_reply(info, child); + if (unlikely(rc)) + mdt_object_unlock(info, child, lhc, 1); RETURN(rc); } @@ -1854,7 +1857,7 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info, mdt_lock_reg_init(lhc, LCK_PR); if (!(child_bits & MDS_INODELOCK_UPDATE) && - mdt_object_exists(child) && !mdt_object_remote(child)) { + !mdt_object_remote(child)) { struct md_attr *ma = &info->mti_attr; ma->ma_valid = 0; @@ -1868,12 +1871,12 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info, * lock and this might save us RPC on later STAT. For * directories, it also let negative dentry cache start * working for this dir. */ - if (ma->ma_valid & MA_INODE && - ma->ma_attr.la_valid & LA_CTIME && - info->mti_mdt->mdt_namespace->ns_ctime_age_limit + - ma->ma_attr.la_ctime < ktime_get_real_seconds()) - child_bits |= MDS_INODELOCK_UPDATE; - } + if (ma->ma_valid & MA_INODE && + ma->ma_attr.la_valid & LA_CTIME && + info->mti_mdt->mdt_namespace->ns_ctime_age_limit + + ma->ma_attr.la_ctime < ktime_get_real_seconds()) + child_bits |= MDS_INODELOCK_UPDATE; + } /* layout lock must be granted in a best-effort way * for IT operations */ @@ -1915,7 +1918,11 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info, GOTO(out_child, rc); } - mdt_pack_secctx_in_reply(info, child); + rc = mdt_pack_secctx_in_reply(info, child); + if (unlikely(rc)) { + mdt_object_unlock(info, child, lhc, 1); + GOTO(out_child, rc); + } lock = ldlm_handle2lock(&lhc->mlh_reg_lh); if (lock) { @@ -1927,8 +1934,7 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info, PLDLMRES(lock->l_resource), PFID(mdt_object_fid(child))); - if (mdt_object_exists(child) && - S_ISREG(lu_object_attr(&child->mot_obj)) && + if (S_ISREG(lu_object_attr(&child->mot_obj)) && !mdt_object_remote(child) && child != parent) { mdt_object_put(info->mti_env, child); rc = mdt_pack_size2body(info, child_fid, diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index 6083c9b..723cd55 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -942,8 +942,8 @@ int mdt_links_read(struct mdt_thread_info *info, struct linkea_data *ldata); int mdt_close_internal(struct mdt_thread_info *info, struct ptlrpc_request *req, struct mdt_body *repbody); -void mdt_pack_secctx_in_reply(struct mdt_thread_info *info, - struct mdt_object *child); +int mdt_pack_secctx_in_reply(struct mdt_thread_info *info, + struct mdt_object *child); static inline struct mdt_device *mdt_dev(struct lu_device *d) { diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 69c916b..71290c2 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -1779,14 +1779,14 @@ int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op) RETURN(rc); } -void mdt_pack_secctx_in_reply(struct mdt_thread_info *info, - struct mdt_object *child) +int mdt_pack_secctx_in_reply(struct mdt_thread_info *info, + struct mdt_object *child) { char *secctx_name; struct lu_buf *buffer; struct mdt_body *repbody; struct req_capsule *pill = info->mti_pill; - int rc; + int rc = 0; if (req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_SERVER) && req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_SERVER) != 0) { @@ -1811,12 +1811,21 @@ void mdt_pack_secctx_in_reply(struct mdt_thread_info *info, if (rc < buffer->lb_len) req_capsule_shrink(pill, &RMF_FILE_SECCTX, rc, RCL_SERVER); + rc = 0; } else { CDEBUG(D_SEC, "security context not found for "DFID": rc = %d\n", PFID(mdt_object_fid(child)), rc); req_capsule_shrink(pill, &RMF_FILE_SECCTX, 0, RCL_SERVER); + /* handling -ENOENT is important because it may change + * object state in DNE env dropping LOHA_EXISTS flag, + * it is important to return that to the caller. + * Check LU-13115 for details. + */ + if (rc != -ENOENT) + rc = 0; } } + return rc; } diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 8baaa48..7b1b1f3 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -1218,7 +1218,9 @@ static int mdt_cross_open(struct mdt_thread_info *info, if (rc != 0) GOTO(out, rc); - mdt_pack_secctx_in_reply(info, o); + rc = mdt_pack_secctx_in_reply(info, o); + if (unlikely(rc)) + GOTO(out, rc); rc = mdt_finish_open(info, NULL, o, open_flags, 0, rep); } else { @@ -1573,7 +1575,9 @@ again: } } - mdt_pack_secctx_in_reply(info, child); + rc = mdt_pack_secctx_in_reply(info, child); + if (unlikely(rc)) + GOTO(out_child, result = rc); rc = mdt_check_resent_lock(info, child, lhc); if (rc < 0) { -- 1.8.3.1