Whamcloud - gitweb
LU-13599 mdt: fix logic of skipping local locks in reply_state 91/39191/4
authorMikhail Pershin <mpershin@whamcloud.com>
Fri, 26 Jun 2020 15:17:06 +0000 (18:17 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 7 Aug 2020 21:12:39 +0000 (21:12 +0000)
The mdt_reint_migrate() controls amount of local locks taken and
prevent the saving too many locks in reply_state by doing local
sync instead. Meanwhile there is flaw in logic of doing that so
they are saved always causing assertion in ptlrpc_save_lock().

Patch adds 'do_sync' local parameter into consideration while
deciding to save local lock or not.

Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: I98cca84825ce5789094fbceb5d1f7975410d134b
Reviewed-on: https://review.whamcloud.com/39191
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Stephane Thiell <sthiell@stanford.edu>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdt/mdt_reint.c
lustre/tests/sanity.sh

index 5d22d31..74f5a8a 100644 (file)
@@ -1578,15 +1578,21 @@ repeat:
 
        EXIT;
 out:
-       if (rc)
+       if (rc) {
                mdt_unlock_list(info, link_locks, rc);
-       else if (local_lnkp_cnt > RS_MAX_LOCKS - 6)
+       } else if (local_lnkp_cnt > RS_MAX_LOCKS - 5) {
+               CDEBUG(D_INFO, "Too many links (%d), sync operations\n",
+                      local_lnkp_cnt);
                /*
                 * parent may have 3 local objects: master object and 2 stripes
-                * (if it's being migrated too); source may have 2 local
-                * objects: master and 1 stripe; target has 1 local object.
+                * (if it's being migrated too); source may have 1 local object
+                * if regular file: master and 1 stripe; target has 1 local
+                * object.
+                * Note, if source is directory it may also have 2 local objects
+                * but can't has hardlinks, so consider only regular files here.
                 */
                rc = 1;
+       }
        return rc;
 }
 
@@ -2117,23 +2123,23 @@ static int mdt_reint_migrate(struct mdt_thread_info *info,
                         mdt_object_child(tobj), &info->mti_spec, ma);
        EXIT;
 
-       mdt_object_unlock(info, tobj, lht, rc);
+       mdt_object_unlock(info, tobj, lht, rc || do_sync);
 put_target:
        mdt_object_put(env, tobj);
 unlock_source:
        mdt_migrate_object_unlock(info, sobj, lhs, seinfo,
-                                 &child_slave_locks, rc);
+                                 &child_slave_locks, rc || do_sync);
 unlock_open_sem:
        if (open_sem_locked)
                up_write(&sobj->mot_open_sem);
 unlock_links:
-       mdt_unlock_list(info, &link_locks, rc);
+       mdt_unlock_list(info, &link_locks, rc || do_sync);
 put_source:
        mdt_object_put(env, sobj);
        mdt_object_put(env, spobj);
 unlock_parent:
        mdt_migrate_object_unlock(info, pobj, lhp, peinfo,
-                                 &parent_slave_locks, rc);
+                                 &parent_slave_locks, rc || do_sync);
 put_parent:
        mdt_object_put(env, pobj);
 unlock_rename:
index 9d91a40..3cd81ee 100755 (executable)
@@ -16454,6 +16454,41 @@ test_230m() {
 }
 run_test 230m "xattrs not changed after dir migration"
 
+test_230r() {
+       [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
+       [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
+       [[ $MDS1_VERSION -ge $(version_code 2.12.5) ]] ||
+               skip "Need MDS version at least 2.12.5"
+
+       # maximum amount of local locks:
+       # parent striped dir - 2 locks
+       # new stripe in parent to migrate to - 1 lock
+       # source and target - 2 locks
+       # Total 5 locks for regular file
+       mkdir -p $DIR/$tdir
+       $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
+       touch $DIR/$tdir/dir1/eee
+
+       # create 4 hardlink for 4 more locks
+       # Total: 9 locks > RS_MAX_LOCKS (8)
+       $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
+       $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
+       $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
+       $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
+       ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
+       ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
+       ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
+       ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
+
+       cancel_lru_locks mdc
+
+       $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
+               error "migrate dir fails"
+
+       rm -rf $DIR/$tdir || error "rm dir failed after migration"
+}
+run_test 230r "migrate with too many local locks"
+
 test_231a()
 {
        # For simplicity this test assumes that max_pages_per_rpc