diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index e2b5e76ca9b4ac8d1af2de67fabf8559eabcffec..e3a59410d7f139d117740dcfff7df99bd95490bf 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -299,6 +299,11 @@ Description: Procfs and llog threads access destoryed import sometimes.
 Details    : Sync the import destoryed process with procfs and llog threads by
 	     the import refcount and semaphore.
 
+Severity   : major
+Bugzilla   : 15674
+Description: mds fails to respond, threads stuck in ldlm_completion_ast
+Details    : Sort source/child resource pair after updating child resource.
+
 -------------------------------------------------------------------------------
 
 
diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c
index e12d6a03fa3df3e642774ba781ebf1334e82e390..3cd251f67c21b1540b778bb94b1b9ace464371cb 100644
--- a/lustre/mds/mds_reint.c
+++ b/lustre/mds/mds_reint.c
@@ -2083,8 +2083,14 @@ int mds_get_parents_children_locked(struct obd_device *obd,
         cleanup_phase = 4; /* target dentry */
 
         inode = (*de_newp)->d_inode;
-        if (inode != NULL)
+        if (inode != NULL) {
+                if (is_bad_inode(inode)) {
+                        CERROR("bad inode returned %lu/%u\n",
+                               inode->i_ino, inode->i_generation);
+                        GOTO(cleanup, rc = -ENOENT);
+                }
                 inode = igrab(inode);
+        }
         if (inode == NULL)
                 goto retry_locks;
 
@@ -2098,8 +2104,6 @@ retry_locks:
         maxres_tgt = &p2_res_id;
         cleanup_phase = 4; /* target dentry */
 
-        if (c1_res_id.name[0] != 0 && res_gt(&c1_res_id, &p1_res_id,NULL,NULL))
-                maxres_src = &c1_res_id;
         if (c2_res_id.name[0] != 0 && res_gt(&c2_res_id, &p2_res_id,NULL,NULL))
                 maxres_tgt = &c2_res_id;
 
@@ -2136,6 +2140,11 @@ retry_locks:
 
         if (!new_name)
                 GOTO(cleanup, rc);
+
+        /* Safe to skip check for child res being all zero */
+        if (res_gt(&c1_res_id, maxres_src, NULL, NULL))
+                maxres_src = &c1_res_id;
+
         /* Step 6b: Re-lookup target child to verify it hasn't changed */
         rc = mds_verify_child(obd, &p2_res_id, &dlm_handles[1], *de_tgtdirp,
                               parent_mode, &c2_res_id, &dlm_handles[3], de_newp,