Whamcloud - gitweb
LU-14361 statahead: return ENOENT for batched statahead 87/51587/21
authorQian Yingjin <qian@ddn.com>
Thu, 6 Jul 2023 03:41:46 +0000 (23:41 -0400)
committerOleg Drokin <green@whamcloud.com>
Tue, 30 Apr 2024 06:53:01 +0000 (06:53 +0000)
When stat on a non-existing file in a batched statahead context,
MDT should return -ENOENT immediately and stop the statahead work.

Otherwise, the client may cache the parent inode with UPDATE lock
and the non-existing dentry under the protection of the parent's
UPDATE lock wrongly.

Add sanity/test_123j to verify it.

Test-Parameters: clientdistro=el9.2 testlist=sanity env=ONLY=123i,ONLY_REPEAT=10
Signed-off-by: Qian Yingjin <qian@ddn.com>
Change-Id: Ia4618f605d2f38ce712e421bcd7b96688bbfbb32
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51587
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Lai Siyao <lai.siyao@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdc/mdc_batch.c
lustre/mdt/mdt_batch.c
lustre/mdt/mdt_handler.c
lustre/tests/sanity.sh

index c2ebd17..82dff48 100644 (file)
@@ -185,6 +185,7 @@ static int mdc_batch_getattr_interpret(struct ptlrpc_request *req,
        struct batch_update_head *head = ouc->ouc_head;
        struct obd_export *exp = head->buh_exp;
        struct req_capsule *pill = item->mop_pill;
+       struct ldlm_reply *lockrep;
 
        req_capsule_subreq_init(pill, &RQF_BUT_GETATTR, req,
                                NULL, repmsg, RCL_CLIENT);
@@ -194,6 +195,12 @@ static int mdc_batch_getattr_interpret(struct ptlrpc_request *req,
        if (rc)
                GOTO(out, rc);
 
+       lockrep = req_capsule_server_get(pill, &RMF_DLM_REP);
+       LASSERT(lockrep != NULL);
+
+       lockrep->lock_policy_res2 =
+               ptlrpc_status_ntoh(lockrep->lock_policy_res2);
+
        rc = mdc_finish_enqueue(exp, pill, einfo, &item->mop_it,
                                &item->mop_lockh, rc);
 out:
index 2dff768..27b17ef 100644 (file)
@@ -320,8 +320,6 @@ int mdt_batch(struct tgt_session_info *tsi)
 
                        tsi->tsi_batch_idx = handled_update_count;
                        rc = h->th_act(tsi);
-                       if (rc)
-                               GOTO(out, rc);
 next:
                        /*
                         * As @repmsg may be changed if the reply buffer is
@@ -332,6 +330,9 @@ next:
                                grown = true;
                        }
 
+                       if (rc)
+                               GOTO(out, rc);
+
                        repmsg->lm_result = rc;
                        mdt_thread_info_reset(info);
 
index 059bd4f..ab01713 100644 (file)
@@ -4849,7 +4849,9 @@ static int mdt_intent_getattr(enum ldlm_intent_flags it_opc,
        if (!mdt_get_disposition(ldlm_rep, DISP_LOOKUP_POS) ||
            ldlm_rep->lock_policy_res2) {
                lhc->mlh_reg_lh.cookie = 0ull;
-               GOTO(out_ucred, rc = ELDLM_LOCK_ABORTED);
+               /* Return error code immediately to stop batched statahead. */
+               GOTO(out_ucred, rc = info->mti_batch_env ? rc :
+                                    ELDLM_LOCK_ABORTED);
        }
 
        rc = mdt_intent_lock_replace(info, lockp, lhc, flags, rc);
index 039a6e8..d0ba156 100755 (executable)
@@ -14824,7 +14824,7 @@ test_123i_base() {
        $LCTL set_param mdc.*.batch_stats=0
 
        echo "statahead_stats (Pre):"
-       lctl get_param -n llite.*.statahead_stats
+       $LCTL get_param -n llite.*.statahead_stats
        eval $iocmd || error "$iocmd failed"
        echo "statahead_stats (Post):"
        $LCTL get_param -n llite.*.statahead_stats
@@ -14876,6 +14876,36 @@ test_123i() {
 }
 run_test 123i "Verify statahead work with the fname indexing pattern"
 
+test_123j() {
+       (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
+
+       $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
+               skip "Server does not support batch RPC"
+
+       local enabled
+
+       enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
+       stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
+       $LCTL set_param llite.*.enable_statahead_fname=1
+
+       stack_trap "rm -rf $DIR/${tdir}.{1..11}"
+
+       mkdir $DIR/${tdir}.{1..10} ||
+               error "failed to mkdir $DIR/${tdir}.{1..10}"
+       cancel_lru_locks mdc
+
+       for i in $(seq 1 10); do
+               stat $DIR/${tdir}.$i || error "failed to stat $DIR/${tdir}.$i"
+       done
+
+       stat $DIR/${tdir}.11
+       $LFS mkdir -i $((MDSCOUNT - 1)) -c 2 -H all_char $DIR/${tdir}.11 ||
+               error "failed to mkdir $DIR/${tdir}.11"
+       touch $DIR/${tdir}.11/$tfile ||
+               error "failed to create file $DIR/${tdir}.11/$tfile"
+}
+run_test 123j "-ENOENT error from batched statahead be handled correctly"
+
 test_124a() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run"
        $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||